diff --git a/.github/workflows/qhelp-pr-preview.yml b/.github/workflows/qhelp-pr-preview.yml index 5cca4faf540..a44ef5ad48d 100644 --- a/.github/workflows/qhelp-pr-preview.yml +++ b/.github/workflows/qhelp-pr-preview.yml @@ -52,7 +52,7 @@ jobs: id: changes run: | (git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.qhelp$' | grep -z -v '.inc.qhelp'; - git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename | xargs --null -rn1 git grep -z -l) | + git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename -z | xargs --null -rn1 git grep -z -l) | grep -z '.qhelp$' | grep -z -v '^-' | sort -z -u > "${RUNNER_TEMP}/paths.txt" - name: QHelp preview diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index f1dfa53f9ba..5ccbbd8592c 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +No user-facing changes. + ## 0.4.0 ### Deprecated APIs diff --git a/cpp/ql/lib/change-notes/released/0.4.1.md b/cpp/ql/lib/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..0d865d0571e --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.4.1.md @@ -0,0 +1,3 @@ +## 0.4.1 + +No user-facing changes. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index cb70ba272d3..fade2cc7c96 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.4.1-dev +version: 0.4.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp 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 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. 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 67e93ea7f6f..c8d9d66e1b9 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 @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql b/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql index 53c96c4beb7..ef9135f1c0a 100644 --- a/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql +++ b/cpp/ql/src/Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql @@ -35,4 +35,4 @@ from LocalVariableOrParameter lv, GlobalVariable gv where lv.getName() = gv.getName() and lv.getFile() = gv.getFile() -select lv, lv.type() + gv.getName() + " hides $@ with the same name.", gv, "a global variable" +select lv, lv.type() + gv.getName() + " hides a $@ with the same name.", gv, "global variable" diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 54dec3b197f..8da02215877 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. + ## 0.4.0 ### New Queries diff --git a/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql b/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql index 87dee3c8e30..298e4c1051a 100644 --- a/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql +++ b/cpp/ql/src/Likely Bugs/ShortLoopVarName.ql @@ -48,5 +48,5 @@ where not coordinatePair(iterationVar, innerVar) select iterationVar, "Iteration variable " + iterationVar.getName() + - " for $@ should have a descriptive name, since there is $@.", outer, "this loop", inner, - "a nested loop" + " for $@ should have a descriptive name, since there is a $@.", outer, "this loop", inner, + "nested loop" diff --git a/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql b/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql index d5892844370..9c456f71bbb 100644 --- a/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql @@ -56,29 +56,26 @@ class VarargsFunction extends Function { result = strictcount(FunctionCall fc | fc = this.getACallToThisFunction()) } - string normalTerminator(int cnt) { + string normalTerminator(int cnt, int totalCount) { + // the terminator is 0 or -1 result = ["0", "-1"] and + // at least 80% of calls have the terminator cnt = this.trailingArgValueCount(result) and - 2 * cnt > this.totalCount() and - not exists(FunctionCall fc, int index | - // terminator value is used in a non-terminating position - this.nonTrailingVarArgValue(fc, index) = result - ) + totalCount = this.totalCount() and + 100 * cnt / totalCount >= 80 and + // terminator value is not used in a non-terminating position + not exists(FunctionCall fc, int index | this.nonTrailingVarArgValue(fc, index) = result) } - predicate isWhitelisted() { - this.hasGlobalName("open") or - this.hasGlobalName("fcntl") or - this.hasGlobalName("ptrace") - } + predicate isWhitelisted() { this.hasGlobalName(["open", "fcntl", "ptrace", "mremap"]) } } -from VarargsFunction f, FunctionCall fc, string terminator, int cnt +from VarargsFunction f, FunctionCall fc, string terminator, int cnt, int totalCount where - terminator = f.normalTerminator(cnt) and + terminator = f.normalTerminator(cnt, totalCount) and fc = f.getACallToThisFunction() and not normalisedExprValue(f.trailingArgumentIn(fc)) = terminator and not f.isWhitelisted() select fc, - "Calls to $@ should use the value " + terminator + " as a terminator (" + cnt + " calls do).", f, - f.getQualifiedName() + "Calls to $@ should use the value " + terminator + " as a terminator (" + cnt + " of " + + totalCount + " calls do).", f, f.getQualifiedName() diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql index 76ee3b60e13..964b2ff33d8 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql @@ -135,5 +135,5 @@ where sink.getNode().asExpr() = va and missingGuard(va, effect) select sink.getNode(), source, sink, - "Arithmetic expression depends on an $@, potentially causing an " + effect + ".", + "This arithmetic expression depends on an $@, potentially causing an " + effect + ".", getExpr(source.getNode()), "uncontrolled value" diff --git a/cpp/ql/src/change-notes/2022-10-06-unterminated-variadic-call.md b/cpp/ql/src/change-notes/2022-10-06-unterminated-variadic-call.md new file mode 100644 index 00000000000..d986ba666ff --- /dev/null +++ b/cpp/ql/src/change-notes/2022-10-06-unterminated-variadic-call.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results. diff --git a/csharp/ql/src/change-notes/2022-09-29-alert-messages.md b/cpp/ql/src/change-notes/released/0.4.1.md similarity index 76% rename from csharp/ql/src/change-notes/2022-09-29-alert-messages.md rename to cpp/ql/src/change-notes/released/0.4.1.md index c6ce24514b8..f5e1dbf00ed 100644 --- a/csharp/ql/src/change-notes/2022-09-29-alert-messages.md +++ b/cpp/ql/src/change-notes/released/0.4.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + * The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 12c12ffe83e..169ac0a41ee 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.4.1-dev +version: 0.4.2-dev groups: - cpp - queries diff --git a/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected index 4aaecc3b3bd..531452ba1b4 100644 --- a/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected +++ b/cpp/ql/test/examples/BadLocking/LocalVariableHidesGlobalVariable.expected @@ -1 +1 @@ -| UnintendedDeclaration.cpp:65:14:65:20 | definition of myMutex | Local variable myMutex hides $@ with the same name. | UnintendedDeclaration.cpp:40:7:40:13 | myMutex | a global variable | +| UnintendedDeclaration.cpp:65:14:65:20 | definition of myMutex | Local variable myMutex hides a $@ with the same name. | UnintendedDeclaration.cpp:40:7:40:13 | myMutex | global variable | diff --git a/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected b/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected index 1ad05dacf8b..d79adba14e4 100644 --- a/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected +++ b/cpp/ql/test/query-tests/Best Practices/Hiding/LocalVariableHidesGlobalVariable/LocalVariableHidesGlobalVariable.expected @@ -1,5 +1,5 @@ -| Hiding.c:22:25:22:26 | definition of gi | Local variable gi hides $@ with the same name. | Hiding.c:2:5:2:6 | gi | a global variable | -| Hiding.c:23:25:23:26 | definition of gj | Local variable gj hides $@ with the same name. | Hiding.c:3:12:3:13 | gj | a global variable | -| Hiding.c:24:25:24:26 | definition of gk | Local variable gk hides $@ with the same name. | Hiding.c:4:12:4:13 | gk | a global variable | -| Hiding.c:37:20:37:21 | definition of g3 | Parameter g3 hides $@ with the same name. | Hiding.c:33:13:33:14 | g3 | a global variable | -| Hiding.c:40:20:40:21 | definition of g5 | Parameter g5 hides $@ with the same name. | Hiding.c:33:21:33:22 | g5 | a global variable | +| Hiding.c:22:25:22:26 | definition of gi | Local variable gi hides a $@ with the same name. | Hiding.c:2:5:2:6 | gi | global variable | +| Hiding.c:23:25:23:26 | definition of gj | Local variable gj hides a $@ with the same name. | Hiding.c:3:12:3:13 | gj | global variable | +| Hiding.c:24:25:24:26 | definition of gk | Local variable gk hides a $@ with the same name. | Hiding.c:4:12:4:13 | gk | global variable | +| Hiding.c:37:20:37:21 | definition of g3 | Parameter g3 hides a $@ with the same name. | Hiding.c:33:13:33:14 | g3 | global variable | +| Hiding.c:40:20:40:21 | definition of g5 | Parameter g5 hides a $@ with the same name. | Hiding.c:33:21:33:22 | g5 | global variable | diff --git a/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected b/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected index 16c5690bf75..22b1f8f4456 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/ShortLoopVarName/ShortLoopVarName.expected @@ -1,4 +1,4 @@ -| ShortLoopVarName.cpp:6:6:6:6 | i | Iteration variable i for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:12:2:18:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:14:3:17:3 | for(...;...;...) ... | a nested loop | -| ShortLoopVarName.cpp:30:13:30:13 | a | Iteration variable a for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:30:2:38:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:34:3:37:3 | for(...;...;...) ... | a nested loop | -| ShortLoopVarName.cpp:73:11:73:11 | y | Iteration variable y for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:73:2:80:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:75:3:79:3 | for(...;...;...) ... | a nested loop | -| ShortLoopVarName.cpp:96:12:96:12 | i | Iteration variable i for $@ should have a descriptive name, since there is $@. | ShortLoopVarName.cpp:96:3:102:3 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:98:4:101:4 | for(...;...;...) ... | a nested loop | +| ShortLoopVarName.cpp:6:6:6:6 | i | Iteration variable i for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:12:2:18:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:14:3:17:3 | for(...;...;...) ... | nested loop | +| ShortLoopVarName.cpp:30:13:30:13 | a | Iteration variable a for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:30:2:38:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:34:3:37:3 | for(...;...;...) ... | nested loop | +| ShortLoopVarName.cpp:73:11:73:11 | y | Iteration variable y for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:73:2:80:2 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:75:3:79:3 | for(...;...;...) ... | nested loop | +| ShortLoopVarName.cpp:96:12:96:12 | i | Iteration variable i for $@ should have a descriptive name, since there is a $@. | ShortLoopVarName.cpp:96:3:102:3 | for(...;...;...) ... | this loop | ShortLoopVarName.cpp:98:4:101:4 | for(...;...;...) ... | nested loop | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/UnterminatedVarargsCall.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/UnterminatedVarargsCall.expected index e1b64faea28..2cf386e2f41 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/UnterminatedVarargsCall.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/UnterminatedVarargsCall.expected @@ -1,9 +1,9 @@ -| more_tests.cpp:23:2:23:12 | call to myFunction2 | Calls to $@ should use the value -1 as a terminator (4 calls do). | more_tests.cpp:5:6:5:16 | myFunction2 | myFunction2 | -| more_tests.cpp:34:2:34:12 | call to myFunction4 | Calls to $@ should use the value 0 as a terminator (3 calls do). | more_tests.cpp:7:6:7:16 | myFunction4 | myFunction4 | -| more_tests.cpp:44:2:44:12 | call to myFunction6 | Calls to $@ should use the value 0 as a terminator (3 calls do). | more_tests.cpp:9:6:9:16 | myFunction6 | myFunction6 | -| more_tests.cpp:55:2:55:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (7 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 | -| more_tests.cpp:56:2:56:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (7 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 | -| tests.c:34:2:34:3 | call to f1 | Calls to $@ should use the value 0 as a terminator (4 calls do). | tests.c:4:6:4:7 | f1 | f1 | -| tests.c:67:2:67:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (3 calls do). | tests.c:24:6:24:7 | f6 | f6 | -| tests.c:68:2:68:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (3 calls do). | tests.c:24:6:24:7 | f6 | f6 | -| tests.c:73:2:73:3 | call to f7 | Calls to $@ should use the value 0 as a terminator (3 calls do). | tests.c:28:6:28:7 | f7 | f7 | +| more_tests.cpp:25:2:25:12 | call to myFunction2 | Calls to $@ should use the value -1 as a terminator (5 of 6 calls do). | more_tests.cpp:5:6:5:16 | myFunction2 | myFunction2 | +| more_tests.cpp:39:2:39:12 | call to myFunction4 | Calls to $@ should use the value 0 as a terminator (5 of 6 calls do). | more_tests.cpp:7:6:7:16 | myFunction4 | myFunction4 | +| more_tests.cpp:49:2:49:12 | call to myFunction6 | Calls to $@ should use the value 0 as a terminator (5 of 6 calls do). | more_tests.cpp:9:6:9:16 | myFunction6 | myFunction6 | +| more_tests.cpp:64:2:64:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (9 of 11 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 | +| more_tests.cpp:65:2:65:12 | call to myFunction7 | Calls to $@ should use the value 0 as a terminator (9 of 11 calls do). | more_tests.cpp:10:6:10:16 | myFunction7 | myFunction7 | +| tests.c:34:2:34:3 | call to f1 | Calls to $@ should use the value 0 as a terminator (4 of 5 calls do). | tests.c:4:6:4:7 | f1 | f1 | +| tests.c:78:2:78:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (10 of 12 calls do). | tests.c:24:6:24:7 | f6 | f6 | +| tests.c:79:2:79:3 | call to f6 | Calls to $@ should use the value -1 as a terminator (10 of 12 calls do). | tests.c:24:6:24:7 | f6 | f6 | +| tests.c:84:2:84:3 | call to f7 | Calls to $@ should use the value 0 as a terminator (12 of 13 calls do). | tests.c:28:6:28:7 | f7 | f7 | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/more_tests.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/more_tests.cpp index a8c34fb490a..d6c9a3915e7 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/more_tests.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/more_tests.cpp @@ -13,27 +13,32 @@ int main() { int x; - myFunction1("%i", 0); // not common enough to be assumed a terminator + myFunction1("%i", 0); // GOOD: not common enough to be assumed a terminator + myFunction1("%i", 0); myFunction1("%i", x); myFunction2(-1); myFunction2(0, -1); myFunction2(0, 1, -1); myFunction2(0, 1, 2, -1); - myFunction2(0, 1, 2, 3); // missing terminator + myFunction2(0, 1, 2, 3, -1); + myFunction2(0, 1, 2, 3, 4); // BAD: missing terminator myFunction3(-1); myFunction3(0, -1); - myFunction3(-1, 1, -1); // -1 isn't a terminator because it's used in a non-terminal position + myFunction3(-1, 1, -1); // GOOD: -1 isn't a terminator because it's used in a non-terminal position myFunction3(0, 1, 2, -1); - myFunction3(0, 1, 2, 3); + myFunction3(0, 1, 2, 3, -1); + myFunction3(0, 1, 2, 3, 4); myFunction4(x, x, 0); myFunction4(0, x, 1, 0); myFunction4(0, 0, 1, 1, 0); - myFunction4(x, 0, 1, 1, 1); // missing terminator + myFunction4(0, x, 1, 1, 1, 0); + myFunction4(0, 0, 1, 1, 1, 1, 0); + myFunction4(x, 0, 1, 1, 1, 1, 1); // BAD: missing terminator - myFunction5('a', 'b', 'c', 0); // ambiguous terminator + myFunction5('a', 'b', 'c', 0); // GOOD: ambiguous terminator myFunction5('a', 'b', 'c', 0); myFunction5('a', 'b', 'c', 0); myFunction5('a', 'b', 'c', -1); @@ -41,19 +46,23 @@ int main() myFunction5('a', 'b', 'c', -1); myFunction6(0.0); - myFunction6(1.0); // missing terminator + myFunction6(1.0); // BAD: missing terminator myFunction6(1.0, 2.0, 0.0); myFunction6(1.0, 2.0, 3.0, 0.0); + myFunction6(1.0, 2.0, 3.0, 4.0, 0.0); + myFunction6(1.0, 2.0, 3.0, 4.0, 5.0, 0.0); myFunction7(NULL); myFunction7("hello", "world", NULL); myFunction7("apple", "banana", "pear", "mango", NULL); myFunction7("dog", "cat", "elephant", "badger", "fish", NULL); myFunction7("one", "two", "three", 0); + myFunction7("four", "five", "six", 0); + myFunction7("seven", "eight", "nine", 0); myFunction7("alpha", "beta", "gamma", 0); myFunction7("", 0); - myFunction7("yes", "no"); // missing terminator - myFunction7(); // missing terminator + myFunction7("yes", "no"); // BAD: missing terminator + myFunction7(); // BAD: missing terminator return 0; } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/tests.c b/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/tests.c index a02a6e02b56..f89d19cf3c7 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/tests.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-121/semmle/tests/tests.c @@ -42,6 +42,7 @@ int main(int argc, char *argv[]) // GOOD: 0 is not common enough to be sure it's a terminator f3("", 0); + f3("", 0); f3("", 10); // GOOD: -1 is not common enough to be sure it's a terminator @@ -50,6 +51,9 @@ int main(int argc, char *argv[]) f4("", -1); f4("", -1); f4("", -1); + f4("", -1); + f4("", -1); + f4("", -1); f4("", 1); // GOOD: no obvious required terminator @@ -61,16 +65,32 @@ int main(int argc, char *argv[]) f5("", 0); f5("", 10); - f6("fsdf", 3, 8, -1); - f6("a", 7, 9, 10, -1); - f6("a", 1, 22, 6, 17, 2, -1); - f6("fgasfgas", 5, 6, argc); // BAD: not (necessarily) terminated with -1 - f6("sadfsaf"); // BAD: not terminated with -1 + f6("a", 3, 8, -1); + f6("b", 7, 9, 10, -1); + f6("c", 1, 22, 6, 17, 2, -1); + f6("d", 1, -1); + f6("e", 1, 2, -1); + f6("f", 1, 2, 3, -1); + f6("g", 1, 2, 3, 4, -1); + f6("h", 5, -1); + f6("i", 5, 6, -1); + f6("j", 5, 6, 7, -1); + f6("k", 5, 6, argc); // BAD: not (necessarily) terminated with -1 + f6("l"); // BAD: not terminated with -1 f7("", 0); f7("", 0); f7("", 0); f7(""); // BAD: not terminated with 0 + f7("", 0); + f7("", 0); + f7("", 0); + f7("", 0); + f7("", 0); + f7("", 0); + f7("", 0); + f7("", 0); + f7("", 0); return 0; } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected index b672d501c5e..3834d769463 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/SAMATE/ArithmeticUncontrolled.expected @@ -52,27 +52,27 @@ nodes | examples.cpp:38:9:38:12 | data | semmle.label | data | subpaths #select -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | -| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | Arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | (unsigned int)... | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:25:31:25:34 | data | examples.cpp:22:26:22:33 | call to rand | examples.cpp:25:31:25:34 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:22:26:22:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | (unsigned int)... | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | +| examples.cpp:38:9:38:12 | data | examples.cpp:35:26:35:33 | call to rand | examples.cpp:38:9:38:12 | data | This arithmetic expression depends on an $@, potentially causing an underflow. | examples.cpp:35:26:35:33 | call to rand | uncontrolled value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected index efec436a131..011f8f73819 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/ArithmeticUncontrolled/ArithmeticUncontrolled.expected @@ -92,31 +92,31 @@ nodes | test.cpp:219:8:219:8 | x | semmle.label | x | subpaths #select -| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | uncontrolled value | -| test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | uncontrolled value | -| test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | uncontrolled value | -| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | -| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | -| test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:14:81:17 | call to rand | uncontrolled value | -| test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:23:81:26 | call to rand | uncontrolled value | -| test.c:127:9:127:9 | r | test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:125:13:125:16 | call to rand | uncontrolled value | -| test.c:133:5:133:5 | r | test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:131:13:131:16 | call to rand | uncontrolled value | -| test.c:139:10:139:10 | r | test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.c:137:13:137:16 | call to rand | uncontrolled value | -| test.c:157:9:157:9 | r | test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r | Arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | -| test.c:157:9:157:9 | r | test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r | Arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | -| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value | -| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value | -| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value | -| test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value | -| test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value | -| test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value | -| test.cpp:154:10:154:10 | b | test.cpp:151:10:151:13 | call to rand | test.cpp:154:10:154:10 | b | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:151:10:151:13 | call to rand | uncontrolled value | -| test.cpp:171:11:171:16 | (int)... | test.cpp:169:11:169:14 | call to rand | test.cpp:171:11:171:16 | (int)... | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | -| test.cpp:171:16:171:16 | y | test.cpp:169:11:169:14 | call to rand | test.cpp:171:16:171:16 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | -| test.cpp:196:7:196:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:196:7:196:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | -| test.cpp:198:7:198:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:198:7:198:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | -| test.cpp:199:7:199:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:199:7:199:7 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | -| test.cpp:204:7:204:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:204:7:204:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | -| test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | -| test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | -| test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | Arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | uncontrolled value | +| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | uncontrolled value | +| test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | uncontrolled value | +| test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | uncontrolled value | +| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | +| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | uncontrolled value | +| test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:14:81:17 | call to rand | uncontrolled value | +| test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:81:23:81:26 | call to rand | uncontrolled value | +| test.c:127:9:127:9 | r | test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:125:13:125:16 | call to rand | uncontrolled value | +| test.c:133:5:133:5 | r | test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:131:13:131:16 | call to rand | uncontrolled value | +| test.c:139:10:139:10 | r | test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.c:137:13:137:16 | call to rand | uncontrolled value | +| test.c:157:9:157:9 | r | test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r | This arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | +| test.c:157:9:157:9 | r | test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r | This arithmetic expression depends on an $@, potentially causing an underflow. | test.c:155:22:155:25 | call to rand | uncontrolled value | +| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value | +| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value | +| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value | +| test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value | +| test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value | +| test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value | +| test.cpp:154:10:154:10 | b | test.cpp:151:10:151:13 | call to rand | test.cpp:154:10:154:10 | b | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:151:10:151:13 | call to rand | uncontrolled value | +| test.cpp:171:11:171:16 | (int)... | test.cpp:169:11:169:14 | call to rand | test.cpp:171:11:171:16 | (int)... | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | +| test.cpp:171:16:171:16 | y | test.cpp:169:11:169:14 | call to rand | test.cpp:171:16:171:16 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:169:11:169:14 | call to rand | uncontrolled value | +| test.cpp:196:7:196:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:196:7:196:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | +| test.cpp:198:7:198:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:198:7:198:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | +| test.cpp:199:7:199:7 | x | test.cpp:189:10:189:13 | call to rand | test.cpp:199:7:199:7 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:189:10:189:13 | call to rand | uncontrolled value | +| test.cpp:204:7:204:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:204:7:204:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | +| test.cpp:205:7:205:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:205:7:205:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | +| test.cpp:208:7:208:7 | y | test.cpp:190:10:190:13 | call to rand | test.cpp:208:7:208:7 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:190:10:190:13 | call to rand | uncontrolled value | +| test.cpp:219:8:219:8 | x | test.cpp:215:11:215:14 | call to rand | test.cpp:219:8:219:8 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:215:11:215:14 | call to rand | uncontrolled value | diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 49d355ec453..afbbf19794a 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.1 + +No user-facing changes. + ## 1.3.0 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.1.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.1.md new file mode 100644 index 00000000000..8dd9964197c --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.3.1.md @@ -0,0 +1,3 @@ +## 1.3.1 + +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 ec16350ed6f..e71b6d081f1 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.3.0 +lastReleaseVersion: 1.3.1 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 648df77d7ff..96ed3493829 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.3.1-dev +version: 1.3.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 49d355ec453..afbbf19794a 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.1 + +No user-facing changes. + ## 1.3.0 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.1.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.1.md new file mode 100644 index 00000000000..8dd9964197c --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.3.1.md @@ -0,0 +1,3 @@ +## 1.3.1 + +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 ec16350ed6f..e71b6d081f1 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.3.0 +lastReleaseVersion: 1.3.1 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 940cdf055f8..888b9099b3d 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.3.1-dev +version: 1.3.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 83b9e7b837c..c303fa86a4a 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries. +* ASP.NET Core controller definition has been made more precise. The amount of introduced taint sources or eliminated false positives should be low though, since the most common pattern is to derive all user defined ASP.NET Core controllers from the standard Controller class, which is not affected. + ## 0.4.0 ### Deprecated APIs diff --git a/csharp/ql/lib/change-notes/2022-09-23-simpletypesanitizer.md b/csharp/ql/lib/change-notes/2022-09-23-simpletypesanitizer.md deleted file mode 100644 index a4d7e4cde7a..00000000000 --- a/csharp/ql/lib/change-notes/2022-09-23-simpletypesanitizer.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries. \ No newline at end of file diff --git a/csharp/ql/lib/change-notes/2022-08-24-aps-net-core-controllers.md b/csharp/ql/lib/change-notes/released/0.4.1.md similarity index 65% rename from csharp/ql/lib/change-notes/2022-08-24-aps-net-core-controllers.md rename to csharp/ql/lib/change-notes/released/0.4.1.md index b3b5006bc57..f3bdef7797c 100644 --- a/csharp/ql/lib/change-notes/2022-08-24-aps-net-core-controllers.md +++ b/csharp/ql/lib/change-notes/released/0.4.1.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + +* `DateTime` expressions are now considered simple type sanitizers. This affects a wide range of security queries. * ASP.NET Core controller definition has been made more precise. The amount of introduced taint sources or eliminated false positives should be low though, since the most common pattern is to derive all user defined ASP.NET Core controllers from the standard Controller class, which is not affected. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 270ae8a65aa..8b00f8845c2 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.4.1-dev +version: 0.4.2-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp 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 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index bf47d9f7f70..8bd7652a52c 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. + ## 0.4.0 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/2022-09-23-alert-messages.md b/csharp/ql/src/change-notes/released/0.4.1.md similarity index 69% rename from java/ql/src/change-notes/2022-09-23-alert-messages.md rename to csharp/ql/src/change-notes/released/0.4.1.md index de46b7752eb..f5e1dbf00ed 100644 --- a/java/ql/src/change-notes/2022-09-23-alert-messages.md +++ b/csharp/ql/src/change-notes/released/0.4.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. \ No newline at end of file +## 0.4.1 + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql b/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql index 513c658cf92..8cee95a3d54 100644 --- a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql +++ b/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql @@ -19,5 +19,5 @@ import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "$@ flows to here and is used in a method of WebClient.", - source.getNode(), "User-provided value" +select sink.getNode(), source, sink, "A method of WebClient depepends on a $@.", source.getNode(), + "user-provided value" diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index 57561944718..753dfb82999 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -17,5 +17,6 @@ import JsonWebTokenHandlerLib from TokenValidationParametersProperty p, CallableAlwaysReturnsTrueHigherPrecision e where e = p.getAnAssignedValue() -select e, "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", p, - p.getQualifiedName().toString(), e, "a callable that always returns \"true\"" +select e, + "JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns \"true\".", + p, p.getQualifiedName().toString() diff --git a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql index 14d0cc02e44..5bb8a1dc6e9 100644 --- a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql +++ b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql @@ -50,5 +50,5 @@ predicate isSuspiciousPropertyName(PropertyRead pr) { from DataFlow::PathNode src, DataFlow::PathNode sink, DataFlowFromMethodToHash conf where conf.hasFlow(src.getNode(), sink.getNode()) select src.getNode(), src, sink, - "The hash is calculated on the process name $@, may be related to a backdoor. Please review the code for possible malicious intent.", - sink.getNode(), "here" + "The hash is calculated on $@, may be related to a backdoor. Please review the code for possible malicious intent.", + sink.getNode(), "this process name" diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index e2721c02552..682028cf7cc 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.4.1-dev +version: 0.4.2-dev groups: - csharp - queries diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected index dc224c9586e..a76e9660cec 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected @@ -1,7 +1,7 @@ -| delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator | delegation-test.cs:101:63:101:186 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:102:63:102:178 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:115:63:115:190 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:116:63:116:180 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:117:63:117:217 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:118:63:118:248 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:119:63:119:177 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator | +| delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | +| delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 1f851cdf663..c38ebde0723 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* Added support for `BeegoInput.RequestBody` as a source of untrusted data. + ## 0.3.0 ### Deprecated APIs diff --git a/go/ql/lib/change-notes/2022-10-06-beego-request-body-source.md b/go/ql/lib/change-notes/released/0.3.1.md similarity index 63% rename from go/ql/lib/change-notes/2022-10-06-beego-request-body-source.md rename to go/ql/lib/change-notes/released/0.3.1.md index 9980b0aadd2..be16eed5d3e 100644 --- a/go/ql/lib/change-notes/2022-10-06-beego-request-body-source.md +++ b/go/ql/lib/change-notes/released/0.3.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.3.1 + +### Minor Analysis Improvements + * Added support for `BeegoInput.RequestBody` as a source of untrusted data. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 8025056129c..3b38291ebb5 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.3.1-dev +version: 0.3.2-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll b/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll index 2cbb350461b..3bc6b5f5eec 100644 --- a/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll +++ b/go/ql/lib/semmle/go/security/InsecureRandomnessCustomizations.qll @@ -64,7 +64,7 @@ module InsecureRandomness { ) } - override string getKind() { result = "this cryptographic algorithm" } + override string getKind() { result = "This cryptographic algorithm" } } /** @@ -75,7 +75,7 @@ module InsecureRandomness { this.getRoot().(FuncDef).getName().regexpMatch("(?i).*(gen(erate)?|salt|make|mk)Password.*") } - override string getKind() { result = "a password-related function" } + override string getKind() { result = "A password-related function" } } /** Gets a package that implements hash algorithms. */ diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 47dabdb2d2e..68880b18281 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.1 + +No user-facing changes. + ## 0.3.0 ### Query Metadata Changes diff --git a/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql b/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql index c846ef16303..93889b0a23e 100644 --- a/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql +++ b/go/ql/src/InconsistentCode/WrappedErrorAlwaysNil.ql @@ -61,4 +61,4 @@ where // } n = DataFlow::BarrierGuard::getABarrierNode() ) -select n, "The first argument to 'errors.Wrap' is always nil" +select n, "The first argument to 'errors.Wrap' is always nil." diff --git a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql index 71ae1ac183a..5c1b4528302 100644 --- a/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql +++ b/go/ql/src/Security/CWE-020/SuspiciousCharacterInRegexp.ql @@ -48,5 +48,5 @@ class Config extends DataFlow::Configuration { from Config c, DataFlow::PathNode source, DataFlow::PathNode sink, string report where c.hasFlowPath(source, sink) and c.isSource(source.getNode(), report) -select source, source, sink, "$@ that is $@ contains " + report, source, "A string literal", sink, +select source, source, sink, "This string literal that is $@ contains " + report, sink, "used as a regular expression" diff --git a/go/ql/src/Security/CWE-117/LogInjection.ql b/go/ql/src/Security/CWE-117/LogInjection.ql index 070788af884..dbf0c767bb3 100644 --- a/go/ql/src/Security/CWE-117/LogInjection.ql +++ b/go/ql/src/Security/CWE-117/LogInjection.ql @@ -17,5 +17,5 @@ import DataFlow::PathGraph from LogInjection::Configuration c, DataFlow::PathNode source, DataFlow::PathNode sink where c.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Log entry depends on a $@.", source.getNode(), +select sink.getNode(), source, sink, "This log entry depends on a $@.", source.getNode(), "user-provided value" diff --git a/go/ql/src/Security/CWE-338/InsecureRandomness.ql b/go/ql/src/Security/CWE-338/InsecureRandomness.ql index 37ec1c21655..e87bbbae37b 100644 --- a/go/ql/src/Security/CWE-338/InsecureRandomness.ql +++ b/go/ql/src/Security/CWE-338/InsecureRandomness.ql @@ -19,7 +19,7 @@ where cfg.hasFlowPath(source, sink) and cfg.isSink(sink.getNode(), kind) and ( - kind != "a password-related function" + kind != "A password-related function" or sink = min(DataFlow::PathNode sink2, int line | @@ -31,5 +31,5 @@ where ) ) select sink.getNode(), source, sink, - "$@ generated with a cryptographically weak RNG is used in $@.", source.getNode(), - "A random number", sink.getNode(), kind + kind + " depends on a $@ generated with a cryptographically weak RNG.", source.getNode(), + "random number" diff --git a/cpp/ql/src/change-notes/2022-09-23-alert-messages.md b/go/ql/src/change-notes/2022-10-07-alert-messages.md similarity index 100% rename from cpp/ql/src/change-notes/2022-09-23-alert-messages.md rename to go/ql/src/change-notes/2022-10-07-alert-messages.md diff --git a/go/ql/src/change-notes/released/0.3.1.md b/go/ql/src/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..9fd4efd6c80 --- /dev/null +++ b/go/ql/src/change-notes/released/0.3.1.md @@ -0,0 +1,3 @@ +## 0.3.1 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/go/ql/src/experimental/CWE-369/DivideByZero.ql b/go/ql/src/experimental/CWE-369/DivideByZero.ql index 8aa12f7f66e..b2e61bef37d 100644 --- a/go/ql/src/experimental/CWE-369/DivideByZero.ql +++ b/go/ql/src/experimental/CWE-369/DivideByZero.ql @@ -54,5 +54,4 @@ class DivideByZeroCheckConfig extends TaintTracking::Configuration { from DataFlow::PathNode source, DataFlow::PathNode sink, DivideByZeroCheckConfig cfg where cfg.hasFlowPath(source, sink) -select sink, source, sink, "Variable $@ might be zero leading to a division-by-zero panic.", sink, - sink.getNode().toString() +select sink, source, sink, "This variable might be zero leading to a division-by-zero panic." diff --git a/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql b/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql index 253d598835d..66fb90664ea 100644 --- a/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql +++ b/go/ql/src/experimental/CWE-400/DatabaseCallInLoop.ql @@ -66,4 +66,4 @@ query predicate edges(CallGraphNode pred, CallGraphNode succ) { from LoopStmt loop, DatabaseAccess dbAccess where edges*(loop, dbAccess.asExpr()) -select dbAccess, loop, dbAccess, "$@ is called in $@", dbAccess, dbAccess.toString(), loop, "a loop" +select dbAccess, loop, dbAccess, "This calls " + dbAccess.toString() + " in a $@.", loop, "loop" diff --git a/go/ql/src/experimental/CWE-918/SSRF.ql b/go/ql/src/experimental/CWE-918/SSRF.ql index 41c41bb18de..4c14969c35f 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.ql +++ b/go/ql/src/experimental/CWE-918/SSRF.ql @@ -19,4 +19,4 @@ from where cfg.hasFlowPath(source, sink) and request = sink.getNode().(ServerSideRequestForgery::Sink).getARequest() -select request, source, sink, "The URL of this request depends on a user-provided value" +select request, source, sink, "The URL of this request depends on a user-provided value." diff --git a/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql b/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql index 3a3c6b1d745..ca17228816c 100644 --- a/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql +++ b/go/ql/src/experimental/IntegerOverflow/IntegerOverflow.ql @@ -11,4 +11,4 @@ import RangeAnalysis from Expr expr where exprMayOverflow(expr) or exprMayUnderflow(expr) -select expr, "this expression may cause an integer overflow" +select expr, "This expression may cause an integer overflow." diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index f454b5ce9d9..574b63f69c1 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.3.1-dev +version: 0.3.2-dev groups: - go - queries diff --git a/go/ql/test/experimental/CWE-369/DivideByZero.expected b/go/ql/test/experimental/CWE-369/DivideByZero.expected index 35a3e399cb7..e80e3295c22 100644 --- a/go/ql/test/experimental/CWE-369/DivideByZero.expected +++ b/go/ql/test/experimental/CWE-369/DivideByZero.expected @@ -24,9 +24,9 @@ nodes | DivideByZero.go:57:17:57:21 | value | semmle.label | value | subpaths #select -| DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:12:16:12:20 | value | value | -| DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:19:16:19:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:19:16:19:20 | value | value | -| DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:26:16:26:20 | value | value | -| DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:33:16:33:20 | value | value | -| DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:40:16:40:20 | value | value | -| DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:57:17:57:21 | value | Variable $@ might be zero leading to a division-by-zero panic. | DivideByZero.go:57:17:57:21 | value | value | +| DivideByZero.go:12:16:12:20 | value | DivideByZero.go:10:12:10:16 | selection of URL : pointer type | DivideByZero.go:12:16:12:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:19:16:19:20 | value | DivideByZero.go:17:12:17:16 | selection of URL : pointer type | DivideByZero.go:19:16:19:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:26:16:26:20 | value | DivideByZero.go:24:12:24:16 | selection of URL : pointer type | DivideByZero.go:26:16:26:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:33:16:33:20 | value | DivideByZero.go:31:12:31:16 | selection of URL : pointer type | DivideByZero.go:33:16:33:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:40:16:40:20 | value | DivideByZero.go:38:12:38:16 | selection of URL : pointer type | DivideByZero.go:40:16:40:20 | value | This variable might be zero leading to a division-by-zero panic. | +| DivideByZero.go:57:17:57:21 | value | DivideByZero.go:54:12:54:16 | selection of URL : pointer type | DivideByZero.go:57:17:57:21 | value | This variable might be zero leading to a division-by-zero panic. | diff --git a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected index bb197203f22..074dfaa134f 100644 --- a/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected +++ b/go/ql/test/experimental/CWE-400/DatabaseCallInLoop.expected @@ -8,6 +8,6 @@ edges | test.go:24:2:26:2 | for statement | test.go:25:3:25:17 | call to runRunQuery | | test.go:25:3:25:17 | call to runRunQuery | test.go:14:1:16:1 | function declaration | #select -| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | $@ is called in $@ | DatabaseCallInLoop.go:9:3:9:41 | call to First | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | a loop | -| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | $@ is called in $@ | test.go:11:2:11:13 | call to Take | call to Take | test.go:20:2:22:2 | for statement | a loop | -| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | $@ is called in $@ | test.go:11:2:11:13 | call to Take | call to Take | test.go:24:2:26:2 | for statement | a loop | +| DatabaseCallInLoop.go:9:3:9:41 | call to First | DatabaseCallInLoop.go:7:2:11:2 | range statement | DatabaseCallInLoop.go:9:3:9:41 | call to First | This calls call to First in a $@. | DatabaseCallInLoop.go:7:2:11:2 | range statement | loop | +| test.go:11:2:11:13 | call to Take | test.go:20:2:22:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:20:2:22:2 | for statement | loop | +| test.go:11:2:11:13 | call to Take | test.go:24:2:26:2 | for statement | test.go:11:2:11:13 | call to Take | This calls call to Take in a $@. | test.go:24:2:26:2 | for statement | loop | diff --git a/go/ql/test/experimental/CWE-918/SSRF.expected b/go/ql/test/experimental/CWE-918/SSRF.expected index a0b9993a4ca..5fdd1775d3d 100644 --- a/go/ql/test/experimental/CWE-918/SSRF.expected +++ b/go/ql/test/experimental/CWE-918/SSRF.expected @@ -55,20 +55,20 @@ nodes | new-tests.go:96:11:96:46 | ...+... | semmle.label | ...+... | subpaths #select -| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value | -| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value | -| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value | -| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value | -| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value | -| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value | -| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value | -| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value | +| builtin.go:22:12:22:63 | call to Get | builtin.go:19:12:19:34 | call to FormValue : string | builtin.go:22:21:22:62 | ...+... | The URL of this request depends on a user-provided value. | +| builtin.go:88:12:88:53 | call to Dial | builtin.go:83:21:83:31 | call to Referer : string | builtin.go:88:27:88:40 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:102:13:102:40 | call to DialConfig | builtin.go:97:21:97:31 | call to Referer : string | builtin.go:101:36:101:49 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:114:3:114:39 | call to Dial | builtin.go:111:21:111:31 | call to Referer : string | builtin.go:114:15:114:28 | untrustedInput | The URL of this request depends on a user-provided value. | +| builtin.go:132:3:132:62 | call to DialContext | builtin.go:129:21:129:31 | call to Referer : string | builtin.go:132:38:132:51 | untrustedInput | The URL of this request depends on a user-provided value. | +| new-tests.go:31:2:31:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:31:11:31:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:32:2:32:58 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:32:11:32:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:35:3:35:59 | call to Get | new-tests.go:26:26:26:30 | &... : pointer type | new-tests.go:35:12:35:58 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:47:2:47:47 | call to Get | new-tests.go:39:18:39:30 | call to Param : string | new-tests.go:47:11:47:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:50:2:50:47 | call to Get | new-tests.go:49:18:49:30 | call to Query : string | new-tests.go:50:11:50:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:68:2:68:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:68:11:68:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:69:2:69:58 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:69:11:69:57 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:74:3:74:59 | call to Get | new-tests.go:62:31:62:38 | selection of Body : ReadCloser | new-tests.go:74:12:74:58 | call to Sprintf | The URL of this request depends on a user-provided value. | +| new-tests.go:79:2:79:47 | call to Get | new-tests.go:78:18:78:24 | selection of URL : pointer type | new-tests.go:79:11:79:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:82:2:82:47 | call to Get | new-tests.go:81:37:81:43 | selection of URL : pointer type | new-tests.go:82:11:82:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:88:2:88:47 | call to Get | new-tests.go:86:10:86:20 | call to Vars : map type | new-tests.go:88:11:88:46 | ...+... | The URL of this request depends on a user-provided value. | +| new-tests.go:96:2:96:47 | call to Get | new-tests.go:95:18:95:45 | call to URLParam : string | new-tests.go:96:11:96:46 | ...+... | The URL of this request depends on a user-provided value. | diff --git a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected index 4ac2411d7ca..43853d29664 100644 --- a/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected +++ b/go/ql/test/query-tests/InconsistentCode/WrappedErrorAlwaysNil/WrappedErrorAlwaysNil.expected @@ -1,4 +1,4 @@ -| WrappedErrorAlwaysNil.go:31:22:31:24 | err | The first argument to 'errors.Wrap' is always nil | -| WrappedErrorAlwaysNil.go:41:14:41:16 | nil | The first argument to 'errors.Wrap' is always nil | -| WrappedErrorAlwaysNil.go:45:14:45:16 | err | The first argument to 'errors.Wrap' is always nil | -| WrappedErrorAlwaysNil.go:49:14:49:21 | localErr | The first argument to 'errors.Wrap' is always nil | +| WrappedErrorAlwaysNil.go:31:22:31:24 | err | The first argument to 'errors.Wrap' is always nil. | +| WrappedErrorAlwaysNil.go:41:14:41:16 | nil | The first argument to 'errors.Wrap' is always nil. | +| WrappedErrorAlwaysNil.go:45:14:45:16 | err | The first argument to 'errors.Wrap' is always nil. | +| WrappedErrorAlwaysNil.go:49:14:49:21 | localErr | The first argument to 'errors.Wrap' is always nil. | diff --git a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected index 130894d0639..cea5780a6c5 100644 --- a/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected +++ b/go/ql/test/query-tests/Security/CWE-020/SuspiciousCharacterInRegexp/SuspiciousCharacterInRegexp.expected @@ -13,14 +13,14 @@ nodes | test.go:23:21:23:36 | "hello\\\\\\bworld" | semmle.label | "hello\\\\\\bworld" | subpaths #select -| SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | A string literal | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | used as a regular expression | -| test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:7:21:7:24 | "\\a" | A string literal | test.go:7:21:7:24 | "\\a" | used as a regular expression | -| test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:9:21:9:26 | "\\\\\\a" | A string literal | test.go:9:21:9:26 | "\\\\\\a" | used as a regular expression | -| test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:10:21:10:27 | "x\\\\\\a" | A string literal | test.go:10:21:10:27 | "x\\\\\\a" | used as a regular expression | -| test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:12:21:12:28 | "\\\\\\\\\\a" | A string literal | test.go:12:21:12:28 | "\\\\\\\\\\a" | used as a regular expression | -| test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | A string literal | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | used as a regular expression | -| test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | A string literal | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | used as a regular expression | -| test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:20:21:20:34 | "hello\\aworld" | A string literal | test.go:20:21:20:34 | "hello\\aworld" | used as a regular expression | -| test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | $@ that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:21:21:21:36 | "hello\\\\\\aworld" | A string literal | test.go:21:21:21:36 | "hello\\\\\\aworld" | used as a regular expression | -| test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:22:21:22:34 | "hello\\bworld" | A string literal | test.go:22:21:22:34 | "hello\\bworld" | used as a regular expression | -| test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | $@ that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:23:21:23:36 | "hello\\\\\\bworld" | A string literal | test.go:23:21:23:36 | "hello\\\\\\bworld" | used as a regular expression | +| SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | SuspiciousCharacterInRegexp.go:6:34:6:55 | "\\bforbidden.host.org" | used as a regular expression | +| test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | test.go:7:21:7:24 | "\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:7:21:7:24 | "\\a" | used as a regular expression | +| test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | test.go:9:21:9:26 | "\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:9:21:9:26 | "\\\\\\a" | used as a regular expression | +| test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | test.go:10:21:10:27 | "x\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:10:21:10:27 | "x\\\\\\a" | used as a regular expression | +| test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | test.go:12:21:12:28 | "\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:12:21:12:28 | "\\\\\\\\\\a" | used as a regular expression | +| test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:14:21:14:30 | "\\\\\\\\\\\\\\a" | used as a regular expression | +| test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:16:21:16:32 | "\\\\\\\\\\\\\\\\\\a" | used as a regular expression | +| test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | test.go:20:21:20:34 | "hello\\aworld" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:20:21:20:34 | "hello\\aworld" | used as a regular expression | +| test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | test.go:21:21:21:36 | "hello\\\\\\aworld" | This string literal that is $@ contains the bell character \\a; did you mean \\\\a, the Vim alphabetic character class (use [[:alpha:]] instead) or \\\\A, the beginning of text? | test.go:21:21:21:36 | "hello\\\\\\aworld" | used as a regular expression | +| test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | test.go:22:21:22:34 | "hello\\bworld" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:22:21:22:34 | "hello\\bworld" | used as a regular expression | +| test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | test.go:23:21:23:36 | "hello\\\\\\bworld" | This string literal that is $@ contains a literal backspace \\b; did you mean \\\\b, a word boundary? | test.go:23:21:23:36 | "hello\\\\\\bworld" | used as a regular expression | 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 be68561ca27..2ba310c6ee1 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 @@ -20,8 +20,8 @@ nodes | sample.go:47:17:47:39 | call to Intn | semmle.label | call to Intn | subpaths #select -| InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | $@ generated with a cryptographically weak RNG is used in $@. | InsecureRandomness.go:12:18:12:40 | call to Intn | A random number | InsecureRandomness.go:12:18:12:40 | call to Intn | a password-related function | -| sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:26:25:26:30 | call to Guid | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:15:49:15:61 | call to Uint32 | A random number | sample.go:26:25:26:30 | call to Guid | this cryptographic algorithm | -| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:34:12:34:40 | call to New | A random number | sample.go:37:25:37:29 | nonce | this cryptographic algorithm | -| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:34:12:34:40 | call to New | A random number | sample.go:37:32:37:36 | nonce | this cryptographic algorithm | -| sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | $@ generated with a cryptographically weak RNG is used in $@. | sample.go:43:17:43:39 | call to Intn | A random number | sample.go:43:17:43:39 | call to Intn | a password-related function | +| InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | InsecureRandomness.go:12:18:12:40 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | InsecureRandomness.go:12:18:12:40 | call to Intn | random number | +| sample.go:26:25:26:30 | call to Guid | sample.go:15:49:15:61 | call to Uint32 : uint32 | sample.go:26:25:26:30 | call to Guid | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:15:49:15:61 | call to Uint32 | random number | +| sample.go:37:25:37:29 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:25:37:29 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | +| sample.go:37:32:37:36 | nonce | sample.go:34:12:34:40 | call to New : pointer type | sample.go:37:32:37:36 | nonce | This cryptographic algorithm depends on a $@ generated with a cryptographically weak RNG. | sample.go:34:12:34:40 | call to New | random number | +| sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | sample.go:43:17:43:39 | call to Intn | A password-related function depends on a $@ generated with a cryptographically weak RNG. | sample.go:43:17:43:39 | call to Intn | random number | diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index a4da1a2ea23..9525522869b 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -25,6 +25,8 @@ def parse_args(): dest='many', help='Build for a single version/kind') parser.add_argument('--single-version', help='Build for a specific version/kind') + parser.add_argument('--single-version-embeddable', action='store_true', + help='When building a single version, build an embeddable extractor (default is standalone)') return parser.parse_args() @@ -235,7 +237,13 @@ def compile_standalone(version): if args.single_version: - compile_standalone(args.single_version) + if args.single_version_embeddable == True: + compile_embeddable(args.single_version) + else: + compile_standalone(args.single_version) +elif args.single_version_embeddable == True: + print("--single-version-embeddable requires --single-version", file=sys.stderr) + sys.exit(1) elif args.many: for version in kotlin_plugin_versions.many_versions: compile_standalone(version) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index fc28db0a3b0..1c34f1d8471 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -155,7 +155,7 @@ open class KotlinFileExtractor( is IrEnumEntry -> { val parentId = useDeclarationParent(declaration.parent, false)?.cast() if (parentId != null) { - extractEnumEntry(declaration, parentId, extractFunctionBodies) + extractEnumEntry(declaration, parentId, extractPrivateMembers, extractFunctionBodies) } Unit } @@ -254,9 +254,23 @@ open class KotlinFileExtractor( } } + fun extractClassInstance(classLabel: Label, c: IrClass, argsIncludingOuterClasses: List?, shouldExtractOutline: Boolean, shouldExtractDetails: Boolean) { + DeclarationStackAdjuster(c).use { + if (shouldExtractOutline) { + extractClassWithoutMembers(c, argsIncludingOuterClasses) + } + + if (shouldExtractDetails) { + val supertypeMode = if (argsIncludingOuterClasses == null) ExtractSupertypesMode.Raw else ExtractSupertypesMode.Specialised(argsIncludingOuterClasses) + extractClassSupertypes(c, classLabel, supertypeMode, true) + extractNonPrivateMemberPrototypes(c, argsIncludingOuterClasses, classLabel) + } + } + } + // `argsIncludingOuterClasses` can be null to describe a raw generic type. // For non-generic types it will be zero-length list. - fun extractClassInstance(c: IrClass, argsIncludingOuterClasses: List?): Label { + private fun extractClassWithoutMembers(c: IrClass, argsIncludingOuterClasses: List?): Label { with("class instance", c) { if (argsIncludingOuterClasses?.isEmpty() == true) { logger.error("Instance without type arguments: " + c.name.asString()) @@ -342,7 +356,7 @@ open class KotlinFileExtractor( // `argsIncludingOuterClasses` can be null to describe a raw generic type. // For non-generic types it will be zero-length list. - fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List?, id: Label) { + private fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List?, id: Label) { with("member prototypes", c) { val typeParamSubstitution = when (argsIncludingOuterClasses) { @@ -1254,7 +1268,7 @@ open class KotlinFileExtractor( } } - private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) { + private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) { with("enum entry", ee) { DeclarationStackAdjuster(ee).use { val id = useEnumEntry(ee) @@ -1265,7 +1279,7 @@ open class KotlinFileExtractor( tw.writeHasLocation(id, locId) tw.writeIsEnumConst(id) - if (extractTypeAccess) { + if (extractFunctionBodies) { val fieldDeclarationId = tw.getFreshIdLabel() tw.writeFielddecls(fieldDeclarationId, parentId) tw.writeFieldDeclaredIn(id, fieldDeclarationId, 0) @@ -1273,6 +1287,10 @@ open class KotlinFileExtractor( extractTypeAccess(type, locId, fieldDeclarationId, 0) } + + ee.correspondingClass?.let { + extractDeclaration(it, extractPrivateMembers, extractFunctionBodies) + } } } } @@ -1769,56 +1787,6 @@ open class KotlinFileExtractor( extractCallValueArguments(id, valueArgsWithDummies + extraArgs, enclosingStmt, enclosingCallable, nextIdx) } - fun extractRawMethodAccess( - syntacticCallTarget: IrFunction, - callsite: IrCall, - enclosingCallable: Label, - callsiteParent: Label, - childIdx: Int, - enclosingStmt: Label, - valueArguments: List, - dispatchReceiver: IrExpression?, - extensionReceiver: IrExpression?, - typeArguments: List = listOf(), - extractClassTypeArguments: Boolean = false, - superQualifierSymbol: IrClassSymbol? = null) { - - val locId = tw.getLocation(callsite) - - if (valueArguments.any { it == null }) { - extractsDefaultsCall( - syntacticCallTarget, - locId, - callsite, - enclosingCallable, - callsiteParent, - childIdx, - enclosingStmt, - valueArguments, - dispatchReceiver, - extensionReceiver - ) - } else { - extractRawMethodAccess( - syntacticCallTarget, - locId, - callsite.type, - enclosingCallable, - callsiteParent, - childIdx, - enclosingStmt, - valueArguments.size, - { argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) }, - dispatchReceiver?.type, - dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } }, - extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } }, - typeArguments, - extractClassTypeArguments, - superQualifierSymbol - ) - } - } - private fun getFunctionInvokeMethod(typeArgs: List): IrFunction? { // For `kotlin.FunctionX` and `kotlin.reflect.KFunctionX` interfaces, we're making sure that we // extract the call to the `invoke` method that does exist, `kotlin.jvm.functions.FunctionX::invoke`. @@ -1877,6 +1845,55 @@ open class KotlinFileExtractor( } } + fun extractRawMethodAccess( + syntacticCallTarget: IrFunction, + callsite: IrCall, + enclosingCallable: Label, + callsiteParent: Label, + childIdx: Int, + enclosingStmt: Label, + valueArguments: List, + dispatchReceiver: IrExpression?, + extensionReceiver: IrExpression?, + typeArguments: List = listOf(), + extractClassTypeArguments: Boolean = false, + superQualifierSymbol: IrClassSymbol? = null) { + + val locId = tw.getLocation(callsite) + + if (valueArguments.any { it == null }) { + extractsDefaultsCall( + syntacticCallTarget, + locId, + callsite, + enclosingCallable, + callsiteParent, + childIdx, + enclosingStmt, + valueArguments, + dispatchReceiver, + extensionReceiver + ) + } else { + extractRawMethodAccess( + syntacticCallTarget, + locId, + callsite.type, + enclosingCallable, + callsiteParent, + childIdx, + enclosingStmt, + valueArguments.size, + { argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) }, + dispatchReceiver?.type, + dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } }, + extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } }, + typeArguments, + extractClassTypeArguments, + superQualifierSymbol + ) + } + } fun extractRawMethodAccess( syntacticCallTarget: IrFunction, @@ -4999,7 +5016,7 @@ open class KotlinFileExtractor( class extends Object implements IntPredicate { Function1 ; public (Function1 ) { this. = ; } - public Boolean accept(Integer i) { return .invoke(i); } + public override Boolean accept(Integer i) { return .invoke(i); } } IntPredicate x = (IntPredicate)new (...); @@ -5079,6 +5096,7 @@ open class KotlinFileExtractor( // the real underlying R Function.apply(T t). forceExtractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, overriddenAttributes = OverriddenFunctionAttributes(id = ids.function, sourceLoc = tw.getLocation(e))) + addModifiers(ids.function, "override") if (st.isSuspendFunctionOrKFunction()) { addModifiers(ids.function, "suspend") } diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index da87bfe1169..1bd27278da0 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -411,16 +411,9 @@ open class KotlinUsesExtractor( if (replacedArgsIncludingOuterClasses == null || replacedArgsIncludingOuterClasses.isNotEmpty()) { // If this is a generic type instantiation or a raw type then it has no // source entity, so we need to extract it here - val extractorWithCSource by lazy { this.withFileOfClass(replacedClass) } - - if (!instanceSeenBefore) { - extractorWithCSource.extractClassInstance(replacedClass, replacedArgsIncludingOuterClasses) - } - - if (inReceiverContext && tw.lm.genericSpecialisationsExtracted.add(classLabelResult.classLabel)) { - val supertypeMode = if (replacedArgsIncludingOuterClasses == null) ExtractSupertypesMode.Raw else ExtractSupertypesMode.Specialised(replacedArgsIncludingOuterClasses) - extractorWithCSource.extractClassSupertypes(replacedClass, classLabel, supertypeMode, true) - extractorWithCSource.extractNonPrivateMemberPrototypes(replacedClass, replacedArgsIncludingOuterClasses, classLabel) + val shouldExtractClassDetails = inReceiverContext && tw.lm.genericSpecialisationsExtracted.add(classLabelResult.classLabel) + if (!instanceSeenBefore || shouldExtractClassDetails) { + this.withFileOfClass(replacedClass).extractClassInstance(classLabel, replacedClass, replacedArgsIncludingOuterClasses, !instanceSeenBefore, shouldExtractClassDetails) } } diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 0f9512eabda..2724a6d3cef 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* Added external flow sources for the intents received in exported Android services. + ## 0.4.0 ### Breaking Changes diff --git a/java/ql/lib/change-notes/2022-09-22-android-deeplink-flow-steps.md b/java/ql/lib/change-notes/2022-09-22-android-deeplink-flow-steps.md new file mode 100644 index 00000000000..1ed229b1e05 --- /dev/null +++ b/java/ql/lib/change-notes/2022-09-22-android-deeplink-flow-steps.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added data flow steps for tainted Android intents that are sent to services and receivers. +* Improved the data flow step for tainted Android intents that are sent to activities so that more cases are covered. diff --git a/java/ql/lib/change-notes/2022-09-22-android-deprecate-contextstartactivitymethod.md b/java/ql/lib/change-notes/2022-09-22-android-deprecate-contextstartactivitymethod.md new file mode 100644 index 00000000000..3500322afad --- /dev/null +++ b/java/ql/lib/change-notes/2022-09-22-android-deprecate-contextstartactivitymethod.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* Deprecated `ContextStartActivityMethod`. Use `StartActivityMethod` instead. diff --git a/java/ql/lib/change-notes/2022-09-23-android-service-sources.md b/java/ql/lib/change-notes/released/0.4.1.md similarity index 66% rename from java/ql/lib/change-notes/2022-09-23-android-service-sources.md rename to java/ql/lib/change-notes/released/0.4.1.md index 812ff07422d..866a6cf524b 100644 --- a/java/ql/lib/change-notes/2022-09-23-android-service-sources.md +++ b/java/ql/lib/change-notes/released/0.4.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + * Added external flow sources for the intents received in exported Android services. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index df1ad196123..fc774265862 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.4.1-dev +version: 0.4.2-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/lib/semmle/code/java/GeneratedFiles.qll b/java/ql/lib/semmle/code/java/GeneratedFiles.qll index a7d1ae628f0..79197653848 100644 --- a/java/ql/lib/semmle/code/java/GeneratedFiles.qll +++ b/java/ql/lib/semmle/code/java/GeneratedFiles.qll @@ -51,9 +51,9 @@ library class MarkerCommentGeneratedFile extends GeneratedFile { /** * A marker comment that indicates that it is in a generated file. */ -private class GeneratedFileMarker extends Top instanceof JavadocElement { +private class GeneratedFileMarker extends Top { GeneratedFileMarker() { - exists(string msg | msg = this.getText() | + exists(string msg | msg = this.(JavadocElement).getText() or msg = this.(KtComment).getText() | msg.regexpMatch("(?i).*\\bGenerated By\\b.*\\bDo not edit\\b.*") or msg.regexpMatch("(?i).*\\bThis (file|class|interface|art[ei]fact) (was|is|(has been)) (?:auto[ -]?)?gener(e?)ated.*") or msg.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*") or 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 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll index ad260c9545c..be38b83e5a7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll @@ -3,9 +3,7 @@ private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSteps -/** - * The class `android.content.Intent`. - */ +/** The class `android.content.Intent`. */ class TypeIntent extends Class { TypeIntent() { this.hasQualifiedName("android.content", "Intent") } } @@ -15,23 +13,17 @@ class TypeComponentName extends Class { TypeComponentName() { this.hasQualifiedName("android.content", "ComponentName") } } -/** - * The class `android.app.Activity`. - */ +/** The class `android.app.Activity`. */ class TypeActivity extends Class { TypeActivity() { this.hasQualifiedName("android.app", "Activity") } } -/** - * The class `android.app.Service`. - */ +/** The class `android.app.Service`. */ class TypeService extends Class { TypeService() { this.hasQualifiedName("android.app", "Service") } } -/** - * The class `android.content.Context`. - */ +/** The class `android.content.Context`. */ class TypeContext extends RefType { // Not inlining this makes it more likely to be used as a sentinel, // which is useful when running Android queries on non-Android projects. @@ -39,25 +31,19 @@ class TypeContext extends RefType { TypeContext() { this.hasQualifiedName("android.content", "Context") } } -/** - * The class `android.content.BroadcastReceiver`. - */ +/** The class `android.content.BroadcastReceiver`. */ class TypeBroadcastReceiver extends Class { TypeBroadcastReceiver() { this.hasQualifiedName("android.content", "BroadcastReceiver") } } -/** - * The method `Activity.getIntent` - */ +/** The method `Activity.getIntent` */ class AndroidGetIntentMethod extends Method { AndroidGetIntentMethod() { this.hasName("getIntent") and this.getDeclaringType() instanceof TypeActivity } } -/** - * The method `BroadcastReceiver.onReceive`. - */ +/** The method `BroadcastReceiver.onReceive`. */ class AndroidReceiveIntentMethod extends Method { AndroidReceiveIntentMethod() { this.hasName("onReceive") and this.getDeclaringType() instanceof TypeBroadcastReceiver @@ -77,8 +63,10 @@ class AndroidServiceIntentMethod extends Method { /** * The method `Context.startActivity` or `startActivities`. + * + * DEPRECATED: Use `StartActivityMethod` instead. */ -class ContextStartActivityMethod extends Method { +deprecated class ContextStartActivityMethod extends Method { ContextStartActivityMethod() { (this.hasName("startActivity") or this.hasName("startActivities")) and this.getDeclaringType() instanceof TypeContext @@ -86,16 +74,57 @@ class ContextStartActivityMethod extends Method { } /** - * Specifies that if an `Intent` is tainted, then so are its synthetic fields. + * The method `Context.startActivity`, `Context.startActivities`, + * `Activity.startActivity`,`Activity.startActivities`, + * `Activity.startActivityForResult`, `Activity.startActivityIfNeeded`, + * `Activity.startNextMatchingActivity`, `Activity.startActivityFromChild`, + * or `Activity.startActivityFromFragment`. */ +class StartActivityMethod extends Method { + StartActivityMethod() { + this.getName().matches("start%Activit%") and + ( + this.getDeclaringType() instanceof TypeContext or + this.getDeclaringType() instanceof TypeActivity + ) + } +} + +/** + * The method `Context.sendBroadcast`, `sendBroadcastAsUser`, + * `sendOrderedBroadcast`, `sendOrderedBroadcastAsUser`, + * `sendStickyBroadcast`, `sendStickyBroadcastAsUser`, + * `sendStickyOrderedBroadcast`, `sendStickyOrderedBroadcastAsUser`, + * or `sendBroadcastWithMultiplePermissions`. + */ +class SendBroadcastMethod extends Method { + SendBroadcastMethod() { + this.getName().matches("send%Broadcast%") and + this.getDeclaringType() instanceof TypeContext + } +} + +/** + * The method `Context.startService`, `startForegroundService`, + * `bindIsolatedService`, `bindService`, or `bindServiceAsUser`. + */ +class StartServiceMethod extends Method { + StartServiceMethod() { + this.hasName([ + "startService", "startForegroundService", "bindIsolatedService", "bindService", + "bindServiceAsUser" + ]) and + this.getDeclaringType() instanceof TypeContext + } +} + +/** Specifies that if an `Intent` is tainted, then so are its synthetic fields. */ private class IntentFieldsInheritTaint extends DataFlow::SyntheticFieldContent, TaintInheritingContent { IntentFieldsInheritTaint() { this.getField().matches("android.content.Intent.%") } } -/** - * The method `Intent.getParcelableExtra`. - */ +/** The method `Intent.getParcelableExtra`. */ class IntentGetParcelableExtraMethod extends Method { IntentGetParcelableExtraMethod() { this.hasName("getParcelableExtra") and @@ -157,9 +186,7 @@ private class BundleExtrasSyntheticField extends SyntheticField { override RefType getType() { result instanceof AndroidBundle } } -/** - * Holds if extras may be implicitly read from the Intent `node`. - */ +/** Holds if extras may be implicitly read from the Intent `node`. */ predicate allowIntentExtrasImplicitRead(DataFlow::Node node, DataFlow::Content c) { node.getType() instanceof TypeIntent and ( @@ -194,25 +221,90 @@ class GrantWriteUriPermissionFlag extends GrantUriPermissionFlag { GrantWriteUriPermissionFlag() { this.hasName("FLAG_GRANT_WRITE_URI_PERMISSION") } } +/** An instantiation of `android.content.Intent`. */ +private class NewIntent extends ClassInstanceExpr { + NewIntent() { this.getConstructedType() instanceof TypeIntent } + + /** Gets the `Class` argument of this call. */ + Argument getClassArg() { + result.getType() instanceof TypeClass and + result = this.getAnArgument() + } +} + +/** A call to a method that starts an Android component. */ +private class StartComponentMethodAccess extends MethodAccess { + StartComponentMethodAccess() { + this.getMethod().overrides*(any(StartActivityMethod m)) or + this.getMethod().overrides*(any(StartServiceMethod m)) or + this.getMethod().overrides*(any(SendBroadcastMethod m)) + } + + /** Gets the intent argument of this call. */ + Argument getIntentArg() { + result.getType() instanceof TypeIntent and + result = this.getAnArgument() + } + + /** Holds if this targets a component of type `targetType`. */ + predicate targetsComponentType(RefType targetType) { + exists(NewIntent newIntent | + DataFlow::localExprFlow(newIntent, this.getIntentArg()) and + newIntent.getClassArg().getType().(ParameterizedType).getATypeArgument() = targetType + ) + } +} + /** - * A value-preserving step from the Intent argument of a `startActivity` call to - * a `getIntent` call in the Activity the Intent pointed to in its constructor. + * A value-preserving step from the intent argument of a `startActivity` call to + * a `getIntent` call in the activity the intent targeted in its constructor. */ private class StartActivityIntentStep extends AdditionalValueStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(MethodAccess startActivity, MethodAccess getIntent, ClassInstanceExpr newIntent | - startActivity.getMethod().overrides*(any(ContextStartActivityMethod m)) and + exists(StartComponentMethodAccess startActivity, MethodAccess getIntent | + startActivity.getMethod().overrides*(any(StartActivityMethod m)) and getIntent.getMethod().overrides*(any(AndroidGetIntentMethod m)) and - newIntent.getConstructedType() instanceof TypeIntent and - DataFlow::localExprFlow(newIntent, startActivity.getArgument(0)) and - newIntent.getArgument(1).getType().(ParameterizedType).getATypeArgument() = - getIntent.getReceiverType() and - n1.asExpr() = startActivity.getArgument(0) and + startActivity.targetsComponentType(getIntent.getReceiverType()) and + n1.asExpr() = startActivity.getIntentArg() and n2.asExpr() = getIntent ) } } +/** + * A value-preserving step from the intent argument of a `sendBroadcast` call to + * the intent parameter in the `onReceive` method of the receiver the + * intent targeted in its constructor. + */ +private class SendBroadcastReceiverIntentStep extends AdditionalValueStep { + override predicate step(DataFlow::Node n1, DataFlow::Node n2) { + exists(StartComponentMethodAccess sendBroadcast, Method onReceive | + sendBroadcast.getMethod().overrides*(any(SendBroadcastMethod m)) and + onReceive.overrides*(any(AndroidReceiveIntentMethod m)) and + sendBroadcast.targetsComponentType(onReceive.getDeclaringType()) and + n1.asExpr() = sendBroadcast.getIntentArg() and + n2.asParameter() = onReceive.getParameter(1) + ) + } +} + +/** + * A value-preserving step from the intent argument of a `startService` call to + * the intent parameter in an `AndroidServiceIntentMethod` of the service the + * intent targeted in its constructor. + */ +private class StartServiceIntentStep extends AdditionalValueStep { + override predicate step(DataFlow::Node n1, DataFlow::Node n2) { + exists(StartComponentMethodAccess startService, Method serviceIntent | + startService.getMethod().overrides*(any(StartServiceMethod m)) and + serviceIntent.overrides*(any(AndroidServiceIntentMethod m)) and + startService.targetsComponentType(serviceIntent.getDeclaringType()) and + n1.asExpr() = startService.getIntentArg() and + n2.asParameter() = serviceIntent.getParameter(0) + ) + } +} + private class IntentBundleFlowSteps extends SummaryModelCsv { override predicate row(string row) { row = diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 4f6633176f4..055d1327b06 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.4.1 + +### New Queries + +* Added a new query, `java/android/webview-debugging-enabled`, to detect instances of WebView debugging being enabled in production builds. + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. +* `PathSanitizer.qll` has been promoted from experimental to the main query pack. This sanitizer was originally [submitted as part of an experimental query by @luchua-bc](https://github.com/github/codeql/pull/7286). +* The queries `java/path-injection`, `java/path-injection-local` and `java/zipslip` now use the sanitizers provided by `PathSanitizer.qll`. + ## 0.4.0 ### New Queries diff --git a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql index 999edaa0b38..1f05298878a 100644 --- a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql @@ -30,6 +30,8 @@ predicate hasTypeTest(Variable v) { or any(SafeCastExpr sce).getExpr() = v.getAnAccess() or + any(ClassExpr c).getExpr() = v.getAnAccess() + or exists(MethodAccess ma | ma.getMethod().getName() = "getClass" and ma.getQualifier() = v.getAnAccess() 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 8fe3d4e6ba6..9f24744fa0c 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 @@ -120,8 +120,12 @@ predicate exposesByStore(Callable c, Field f, Expr why, string whyText) { from Callable c, Field f, Expr why, string whyText where - exposesByReturn(c, f, why, whyText) or - exposesByStore(c, f, why, whyText) + ( + exposesByReturn(c, f, why, whyText) or + exposesByStore(c, f, why, whyText) + ) and + // Kotlin properties expose internal representation, but it's not accidental, so ignore them + 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 diff --git a/java/ql/src/change-notes/2022-08-25-path-sanitizer.md b/java/ql/src/change-notes/2022-08-25-path-sanitizer.md deleted file mode 100644 index a883561d59c..00000000000 --- a/java/ql/src/change-notes/2022-08-25-path-sanitizer.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- - -* `PathSanitizer.qll` has been promoted from experimental to the main query pack. This sanitizer was originally [submitted as part of an experimental query by @luchua-bc](https://github.com/github/codeql/pull/7286). -* The queries `java/path-injection`, `java/path-injection-local` and `java/zipslip` now use the sanitizers provided by `PathSanitizer.qll`. \ No newline at end of file diff --git a/java/ql/src/change-notes/2022-08-31-webview-dubugging.md b/java/ql/src/change-notes/2022-08-31-webview-dubugging.md deleted file mode 100644 index 8e6295efeb3..00000000000 --- a/java/ql/src/change-notes/2022-08-31-webview-dubugging.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `java/android/webview-debugging-enabled`, to detect instances of WebView debugging being enabled in production builds. \ No newline at end of file diff --git a/java/ql/src/change-notes/released/0.4.1.md b/java/ql/src/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..0ac482407a7 --- /dev/null +++ b/java/ql/src/change-notes/released/0.4.1.md @@ -0,0 +1,11 @@ +## 0.4.1 + +### New Queries + +* Added a new query, `java/android/webview-debugging-enabled`, to detect instances of WebView debugging being enabled in production builds. + +### Minor Analysis Improvements + +* The alert message of many queries have been changed to better follow the style guide and make the message consistent with other languages. +* `PathSanitizer.qll` has been promoted from experimental to the main query pack. This sanitizer was originally [submitted as part of an experimental query by @luchua-bc](https://github.com/github/codeql/pull/7286). +* The queries `java/path-injection`, `java/path-injection-local` and `java/zipslip` now use the sanitizers provided by `PathSanitizer.qll`. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 5f93a953ea6..d74415382a4 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.4.1-dev +version: 0.4.2-dev groups: - java - queries diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected new file mode 100644 index 00000000000..6b4abd0e1a4 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.expected @@ -0,0 +1 @@ +| Generated.kt:0:0:0:0 | Generated | diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.kt new file mode 100644 index 00000000000..4aa496a1b7d --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.kt @@ -0,0 +1,3 @@ +// This file was auto generated by me + +class B \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.ql b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.ql new file mode 100644 index 00000000000..131acde1993 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/Generated.ql @@ -0,0 +1,4 @@ +import java + +from GeneratedFile f +select f diff --git a/java/ql/test/kotlin/library-tests/GeneratedFiles/NonGenerated.kt b/java/ql/test/kotlin/library-tests/GeneratedFiles/NonGenerated.kt new file mode 100644 index 00000000000..4fd8af3f7a3 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/GeneratedFiles/NonGenerated.kt @@ -0,0 +1,3 @@ +// This file was not generated + +class A \ No newline at end of file diff --git a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected index 8b4da235ba0..7e636762d16 100644 --- a/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected +++ b/java/ql/test/kotlin/library-tests/exprs/funcExprs.expected @@ -42,7 +42,7 @@ memberRefExprs | kFunctionInvoke.kt:8:44:8:47 | ...::... | kFunctionInvoke.kt:8:44:8:47 | invoke | invoke(java.lang.String) | kFunctionInvoke.kt:8:44:8:47 | new Function1(...) { ... } | | samConversion.kt:5:27:5:31 | ...::... | samConversion.kt:5:27:5:31 | invoke | invoke(int,int) | samConversion.kt:5:27:5:31 | new Function2(...) { ... } | | samConversion.kt:41:13:41:16 | ...::... | samConversion.kt:41:13:41:16 | invoke | invoke(java.lang.Object[]) | samConversion.kt:41:13:41:16 | new FunctionN(...) { ... } | -modifiers +lambda_modifiers | delegatedProperties.kt:6:32:9:9 | ...->... | delegatedProperties.kt:6:32:9:9 | invoke | override, public | | funcExprs.kt:22:26:22:33 | ...->... | funcExprs.kt:22:26:22:33 | invoke | override, public | | funcExprs.kt:23:26:23:33 | ...->... | funcExprs.kt:23:26:23:33 | invoke | override, public | @@ -74,6 +74,173 @@ modifiers | samConversion.kt:43:31:45:68 | ...->... | samConversion.kt:43:31:45:68 | invoke | public | | samConversion.kt:46:32:46:44 | ...->... | samConversion.kt:46:32:46:44 | invoke | override, public | | samConversion.kt:58:30:58:45 | ...->... | samConversion.kt:58:30:58:45 | invoke | override, public, suspend | +anon_class_member_modifiers +| delegatedProperties.kt:6:24:9:9 | new KProperty0(...) { ... } | delegatedProperties.kt:6:24:9:9 | get | override, public | +| delegatedProperties.kt:6:24:9:9 | new KProperty0(...) { ... } | delegatedProperties.kt:6:24:9:9 | invoke | override, public | +| delegatedProperties.kt:6:32:9:9 | new Function0(...) { ... } | delegatedProperties.kt:6:32:9:9 | invoke | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | get | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | invoke | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | invoke | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | set | override, public | +| delegatedProperties.kt:19:31:19:51 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:19:31:19:51 | set | override, public | +| delegatedProperties.kt:23:26:23:31 | new KProperty0(...) { ... } | delegatedProperties.kt:23:26:23:31 | get | override, public | +| delegatedProperties.kt:23:26:23:31 | new KProperty0(...) { ... } | delegatedProperties.kt:23:26:23:31 | invoke | override, public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | getCurValue | public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:26:13:26:28 | setCurValue | public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:27:22:27:88 | getValue | override, public | +| delegatedProperties.kt:25:64:31:9 | new ReadWriteProperty(...) { ... } | delegatedProperties.kt:28:22:30:13 | setValue | override, public | +| delegatedProperties.kt:33:27:33:47 | new KProperty0(...) { ... } | delegatedProperties.kt:33:27:33:47 | get | override, public | +| delegatedProperties.kt:33:27:33:47 | new KProperty0(...) { ... } | delegatedProperties.kt:33:27:33:47 | invoke | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | get | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | get | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | invoke | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | invoke | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | set | override, public | +| delegatedProperties.kt:34:28:34:48 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:34:28:34:48 | set | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | get | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | get | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | invoke | override, public | +| delegatedProperties.kt:39:31:39:51 | new KProperty0(...) { ... } | delegatedProperties.kt:39:31:39:51 | invoke | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | get | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | get | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | invoke | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | invoke | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | set | override, public | +| delegatedProperties.kt:42:27:42:47 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:42:27:42:47 | set | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | get | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | get | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | invoke | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | invoke | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | set | override, public | +| delegatedProperties.kt:66:33:66:50 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:66:33:66:50 | set | override, public | +| delegatedProperties.kt:66:36:66:50 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:66:36:66:50 | get | override, public | +| delegatedProperties.kt:66:36:66:50 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:66:36:66:50 | invoke | override, public | +| delegatedProperties.kt:66:36:66:50 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:66:36:66:50 | set | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | get | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | get | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | invoke | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | invoke | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | set | override, public | +| delegatedProperties.kt:67:33:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:33:67:53 | set | override, public | +| delegatedProperties.kt:67:36:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:36:67:53 | get | override, public | +| delegatedProperties.kt:67:36:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:36:67:53 | invoke | override, public | +| delegatedProperties.kt:67:36:67:53 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:67:36:67:53 | set | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | get | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | get | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | invoke | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | invoke | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | set | override, public | +| delegatedProperties.kt:69:36:69:56 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:69:36:69:56 | set | override, public | +| delegatedProperties.kt:69:39:69:56 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:69:39:69:56 | get | override, public | +| delegatedProperties.kt:69:39:69:56 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:69:39:69:56 | invoke | override, public | +| delegatedProperties.kt:69:39:69:56 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:69:39:69:56 | set | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | get | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | get | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | invoke | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | invoke | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | set | override, public | +| delegatedProperties.kt:70:36:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:36:70:59 | set | override, public | +| delegatedProperties.kt:70:39:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:39:70:59 | get | override, public | +| delegatedProperties.kt:70:39:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:39:70:59 | invoke | override, public | +| delegatedProperties.kt:70:39:70:59 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:70:39:70:59 | set | override, public | +| delegatedProperties.kt:72:36:72:56 | new KProperty1(...) { ... } | delegatedProperties.kt:72:36:72:56 | get | override, public | +| delegatedProperties.kt:72:36:72:56 | new KProperty1(...) { ... } | delegatedProperties.kt:72:36:72:56 | invoke | override, public | +| delegatedProperties.kt:72:39:72:56 | new KProperty0(...) { ... } | delegatedProperties.kt:72:39:72:56 | get | override, public | +| delegatedProperties.kt:72:39:72:56 | new KProperty0(...) { ... } | delegatedProperties.kt:72:39:72:56 | invoke | override, public | +| delegatedProperties.kt:73:36:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:36:73:56 | get | override, public | +| delegatedProperties.kt:73:36:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:36:73:56 | invoke | override, public | +| delegatedProperties.kt:73:39:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:39:73:56 | get | override, public | +| delegatedProperties.kt:73:39:73:56 | new KProperty1(...) { ... } | delegatedProperties.kt:73:39:73:56 | invoke | override, public | +| delegatedProperties.kt:75:39:75:78 | new KProperty1(...) { ... } | delegatedProperties.kt:75:39:75:78 | get | override, public | +| delegatedProperties.kt:75:39:75:78 | new KProperty1(...) { ... } | delegatedProperties.kt:75:39:75:78 | invoke | override, public | +| delegatedProperties.kt:75:42:75:78 | new KProperty0(...) { ... } | delegatedProperties.kt:75:42:75:78 | get | override, public | +| delegatedProperties.kt:75:42:75:78 | new KProperty0(...) { ... } | delegatedProperties.kt:75:42:75:78 | invoke | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | get | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | get | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | invoke | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | invoke | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | set | override, public | +| delegatedProperties.kt:77:34:77:49 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:77:34:77:49 | set | override, public | +| delegatedProperties.kt:77:37:77:49 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:77:37:77:49 | get | override, public | +| delegatedProperties.kt:77:37:77:49 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:77:37:77:49 | invoke | override, public | +| delegatedProperties.kt:77:37:77:49 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:77:37:77:49 | set | override, public | +| delegatedProperties.kt:79:18:79:38 | new KProperty1(...) { ... } | delegatedProperties.kt:79:18:79:38 | get | override, public | +| delegatedProperties.kt:79:18:79:38 | new KProperty1(...) { ... } | delegatedProperties.kt:79:18:79:38 | invoke | override, public | +| delegatedProperties.kt:79:21:79:38 | new KProperty0(...) { ... } | delegatedProperties.kt:79:21:79:38 | get | override, public | +| delegatedProperties.kt:79:21:79:38 | new KProperty0(...) { ... } | delegatedProperties.kt:79:21:79:38 | invoke | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | get | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | get | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | invoke | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | invoke | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | set | override, public | +| delegatedProperties.kt:82:37:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:37:82:54 | set | override, public | +| delegatedProperties.kt:82:40:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:40:82:54 | get | override, public | +| delegatedProperties.kt:82:40:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:40:82:54 | invoke | override, public | +| delegatedProperties.kt:82:40:82:54 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:82:40:82:54 | set | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | get | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | get | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | invoke | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | invoke | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | set | override, public | +| delegatedProperties.kt:87:31:87:46 | new KMutableProperty1(...) { ... } | delegatedProperties.kt:87:31:87:46 | set | override, public | +| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | get | override, public | +| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | invoke | override, public | +| delegatedProperties.kt:87:34:87:46 | new KMutableProperty0(...) { ... } | delegatedProperties.kt:87:34:87:46 | set | override, public | +| exprs.kt:189:16:191:9 | new Interface1(...) { ... } | exprs.kt:190:13:190:49 | getA3 | public | +| funcExprs.kt:22:26:22:33 | new Function0(...) { ... } | funcExprs.kt:22:26:22:33 | invoke | override, public | +| funcExprs.kt:23:26:23:33 | new Function0(...) { ... } | funcExprs.kt:23:26:23:33 | invoke | override, public | +| funcExprs.kt:24:26:24:33 | new Function0(...) { ... } | funcExprs.kt:24:26:24:33 | invoke | override, public | +| funcExprs.kt:25:29:25:38 | new Function1(...) { ... } | funcExprs.kt:25:29:25:38 | invoke | override, public | +| funcExprs.kt:26:29:26:34 | new Function1(...) { ... } | funcExprs.kt:26:29:26:34 | invoke | override, public | +| funcExprs.kt:27:29:27:42 | new Function1(...) { ... } | funcExprs.kt:27:29:27:42 | invoke | override, public | +| funcExprs.kt:29:29:29:37 | new Function1(...) { ... } | funcExprs.kt:29:29:29:37 | invoke | override, public | +| funcExprs.kt:30:28:30:50 | new Function2(...) { ... } | funcExprs.kt:30:28:30:50 | invoke | override, public | +| funcExprs.kt:31:28:31:40 | new Function2(...) { ... } | funcExprs.kt:31:28:31:40 | invoke | override, public | +| funcExprs.kt:32:28:32:44 | new Function2(...) { ... } | funcExprs.kt:32:28:32:44 | invoke | override, public | +| funcExprs.kt:33:28:33:51 | new Function1>(...) { ... } | funcExprs.kt:33:28:33:51 | invoke | override, public | +| funcExprs.kt:33:37:33:47 | new Function1(...) { ... } | funcExprs.kt:33:37:33:47 | invoke | override, public | +| funcExprs.kt:35:29:35:112 | new Function22(...) { ... } | funcExprs.kt:35:29:35:112 | invoke | override, public | +| funcExprs.kt:36:29:36:117 | new FunctionN(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | override, public | +| funcExprs.kt:36:29:36:117 | new FunctionN(...) { ... } | funcExprs.kt:36:29:36:117 | invoke | public | +| funcExprs.kt:38:26:38:38 | new Function0(...) { ... } | funcExprs.kt:38:26:38:38 | invoke | override, public | +| funcExprs.kt:39:26:39:36 | new Function0(...) { ... } | funcExprs.kt:39:26:39:36 | invoke | override, public | +| funcExprs.kt:40:29:40:41 | new Function1(...) { ... } | funcExprs.kt:40:29:40:41 | invoke | override, public | +| funcExprs.kt:41:29:41:39 | new Function2(...) { ... } | funcExprs.kt:41:29:41:39 | invoke | override, public | +| funcExprs.kt:42:29:42:33 | new Function1(...) { ... } | funcExprs.kt:42:29:42:33 | invoke | override, public | +| funcExprs.kt:43:28:43:34 | new Function2(...) { ... } | funcExprs.kt:43:28:43:34 | invoke | override, public | +| funcExprs.kt:44:29:44:42 | new Function22(...) { ... } | funcExprs.kt:44:29:44:42 | invoke | override, public | +| funcExprs.kt:45:29:45:42 | new FunctionN(...) { ... } | funcExprs.kt:45:29:45:42 | invoke | override, public | +| funcExprs.kt:46:30:46:41 | new FunctionN(...) { ... } | funcExprs.kt:46:30:46:41 | invoke | override, public | +| funcExprs.kt:49:26:49:32 | new Function0(...) { ... } | funcExprs.kt:49:26:49:32 | invoke | override, public | +| funcExprs.kt:51:8:51:16 | new Function0(...) { ... } | funcExprs.kt:51:8:51:16 | invoke | override, public | +| funcExprs.kt:75:12:75:22 | new Function1>,String>(...) { ... } | funcExprs.kt:75:12:75:22 | invoke | override, public | +| funcExprs.kt:83:31:83:51 | new Function1(...) { ... } | funcExprs.kt:83:31:83:51 | invoke | override, public | +| funcExprs.kt:86:39:86:59 | new Function1(...) { ... } | funcExprs.kt:86:39:86:59 | invoke | override, public, suspend | +| funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | override, public | +| funcExprs.kt:90:15:90:69 | new FunctionN(...) { ... } | funcExprs.kt:90:15:90:69 | invoke | public | +| funcExprs.kt:94:15:94:67 | new Function22(...) { ... } | funcExprs.kt:94:15:94:67 | invoke | override, public, suspend | +| kFunctionInvoke.kt:8:44:8:47 | new Function1(...) { ... } | kFunctionInvoke.kt:8:44:8:47 | invoke | override, public | +| samConversion.kt:2:18:2:45 | new IntPredicate(...) { ... } | samConversion.kt:2:18:2:45 | accept | override, public | +| samConversion.kt:2:31:2:45 | new Function1(...) { ... } | samConversion.kt:2:31:2:45 | invoke | override, public | +| samConversion.kt:4:14:4:42 | new InterfaceFn1(...) { ... } | samConversion.kt:4:14:4:42 | fn1 | override, public | +| samConversion.kt:4:27:4:42 | new Function2(...) { ... } | samConversion.kt:4:27:4:42 | invoke | override, public | +| samConversion.kt:5:14:5:32 | new InterfaceFn1(...) { ... } | samConversion.kt:5:14:5:32 | fn1 | override, public | +| samConversion.kt:5:27:5:31 | new Function2(...) { ... } | samConversion.kt:5:27:5:31 | invoke | override, public | +| samConversion.kt:7:13:7:46 | new InterfaceFnExt1(...) { ... } | samConversion.kt:7:13:7:46 | ext | override, public | +| samConversion.kt:7:29:7:46 | new Function2(...) { ... } | samConversion.kt:7:29:7:46 | invoke | override, public | +| samConversion.kt:9:13:13:6 | new IntPredicate(...) { ... } | samConversion.kt:9:13:13:6 | accept | override, public | +| samConversion.kt:9:33:11:5 | new Function1(...) { ... } | samConversion.kt:9:33:11:5 | invoke | override, public | +| samConversion.kt:11:12:13:5 | new Function1(...) { ... } | samConversion.kt:11:12:13:5 | invoke | override, public | +| samConversion.kt:41:13:41:16 | new FunctionN(...) { ... } | samConversion.kt:41:13:41:16 | invoke | override, public | +| samConversion.kt:42:13:42:32 | new BigArityPredicate(...) { ... } | samConversion.kt:42:13:42:32 | accept | override, public | +| samConversion.kt:43:13:45:68 | new BigArityPredicate(...) { ... } | samConversion.kt:43:13:45:68 | accept | override, public | +| samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | override, public | +| samConversion.kt:43:31:45:68 | new FunctionN(...) { ... } | samConversion.kt:43:31:45:68 | invoke | public | +| samConversion.kt:46:13:46:44 | new SomePredicate(...) { ... } | samConversion.kt:46:13:46:44 | fn | override, public | +| samConversion.kt:46:32:46:44 | new Function1(...) { ... } | samConversion.kt:46:32:46:44 | invoke | override, public | +| samConversion.kt:58:14:58:45 | new InterfaceFn1Sus(...) { ... } | samConversion.kt:58:14:58:45 | fn1 | override, public, suspend | +| samConversion.kt:58:30:58:45 | new Function2(...) { ... } | samConversion.kt:58:30:58:45 | invoke | override, public, suspend | nonOverrideInvoke | funcExprs.kt:36:29:36:117 | ...->... | funcExprs.kt:36:29:36:117 | invoke | 23 | | funcExprs.kt:90:15:90:69 | ...->... | funcExprs.kt:90:15:90:69 | invoke | 23 | diff --git a/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql b/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql index fa2b5fda2a2..f6e233336f3 100644 --- a/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql +++ b/java/ql/test/kotlin/library-tests/exprs/funcExprs.ql @@ -19,11 +19,16 @@ query predicate memberRefExprs(MemberRefExpr e, Method m, string signature, Anon e.getAnonymousClass() = an } -query predicate modifiers(LambdaExpr le, Method m, string modifiers) { +query predicate lambda_modifiers(LambdaExpr le, Method m, string modifiers) { le.getAnonymousClass().getAMethod() = m and modifiers = concat(string s | m.hasModifier(s) | s, ", ") } +query predicate anon_class_member_modifiers(AnonymousClass ac, Method m, string modifiers) { + ac.getAMethod() = m and + modifiers = concat(string s | m.hasModifier(s) | s, ", ") +} + query predicate nonOverrideInvoke(LambdaExpr le, Method m, int pCount) { le.getAnonymousClass().getAMethod() = m and not m.hasModifier("override") and diff --git a/java/ql/test/kotlin/library-tests/methods/clinit.expected b/java/ql/test/kotlin/library-tests/methods/clinit.expected index ea5b5392d82..3bf5f170f08 100644 --- a/java/ql/test/kotlin/library-tests/methods/clinit.expected +++ b/java/ql/test/kotlin/library-tests/methods/clinit.expected @@ -1,2 +1,3 @@ | clinit.kt:0:0:0:0 | | file://:0:0:0:0 | void | | enumClass.kt:0:0:0:0 | | file://:0:0:0:0 | void | +| enumClass.kt:0:0:0:0 | | file://:0:0:0:0 | void | diff --git a/java/ql/test/kotlin/library-tests/methods/enumClass.kt b/java/ql/test/kotlin/library-tests/methods/enumClass.kt index 89568c0d5f4..9f3acad608a 100644 --- a/java/ql/test/kotlin/library-tests/methods/enumClass.kt +++ b/java/ql/test/kotlin/library-tests/methods/enumClass.kt @@ -2,3 +2,15 @@ enum class EnumClass(val v: Int) { enum1(1), enum2(1) } + +enum class EnumWithFunctions { + + VAL { + override fun f(i: Int) = i + override fun g(i: Int) = this.f(i) + i + }; + + abstract fun f(i: Int): Int + abstract fun g(i: Int): Int + +} diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index 77033a11bbe..bf15f66b6ef 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -226,6 +226,10 @@ | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass[] | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions | TypeAccess | +| enumClass.kt:0:0:0:0 | EnumWithFunctions[] | TypeAccess | +| enumClass.kt:0:0:0:0 | String | TypeAccess | | enumClass.kt:0:0:0:0 | String | TypeAccess | | enumClass.kt:1:1:4:1 | Enum | TypeAccess | | enumClass.kt:1:1:4:1 | EnumClass | TypeAccess | @@ -252,6 +256,33 @@ | enumClass.kt:3:5:3:12 | EnumClass.enum2 | VarAccess | | enumClass.kt:3:5:3:12 | new EnumClass(...) | ClassInstanceExpr | | enumClass.kt:3:11:3:11 | 1 | IntegerLiteral | +| enumClass.kt:6:1:16:1 | Enum | TypeAccess | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess | +| enumClass.kt:6:1:16:1 | new Enum(...) | ClassInstanceExpr | +| enumClass.kt:8:3:11:4 | ...=... | KtInitializerAssignExpr | +| enumClass.kt:8:3:11:4 | | ImplicitCoercionToUnitExpr | +| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess | +| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess | +| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess | +| enumClass.kt:8:3:11:4 | EnumWithFunctions.VAL | VarAccess | +| enumClass.kt:8:3:11:4 | Unit | TypeAccess | +| enumClass.kt:8:3:11:4 | VAL | TypeAccess | +| enumClass.kt:8:3:11:4 | new EnumWithFunctions(...) | ClassInstanceExpr | +| enumClass.kt:8:3:11:4 | new VAL(...) | ClassInstanceExpr | +| enumClass.kt:9:14:9:30 | int | TypeAccess | +| enumClass.kt:9:20:9:25 | int | TypeAccess | +| enumClass.kt:9:30:9:30 | i | VarAccess | +| enumClass.kt:10:14:10:42 | int | TypeAccess | +| enumClass.kt:10:20:10:25 | int | TypeAccess | +| enumClass.kt:10:30:10:33 | this | ThisAccess | +| enumClass.kt:10:30:10:42 | ... + ... | AddExpr | +| enumClass.kt:10:35:10:38 | f(...) | MethodAccess | +| enumClass.kt:10:37:10:37 | i | VarAccess | +| enumClass.kt:10:42:10:42 | i | VarAccess | +| enumClass.kt:13:12:13:29 | int | TypeAccess | +| enumClass.kt:13:18:13:23 | int | TypeAccess | +| enumClass.kt:14:12:14:29 | int | TypeAccess | +| enumClass.kt:14:18:14:23 | int | TypeAccess | | methods2.kt:4:1:5:1 | Unit | TypeAccess | | methods2.kt:4:26:4:31 | int | TypeAccess | | methods2.kt:4:34:4:39 | int | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.expected b/java/ql/test/kotlin/library-tests/methods/methods.expected index 69c8e1ab214..8ee20aac587 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.expected +++ b/java/ql/test/kotlin/library-tests/methods/methods.expected @@ -29,6 +29,13 @@ methods | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:22:1:31 | getV | getV() | public | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | | () | | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:13:12:13:29 | f | f(int) | public | | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:14:12:14:29 | g | g(int) | public | | +| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:9:14:9:30 | f | f(int) | override, public | | +| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:10:14:10:42 | g | g(int) | override, public | | | methods2.kt:0:0:0:0 | Methods2Kt | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | fooBarTopLevelMethod(int,int) | public, static | | | methods2.kt:7:1:10:1 | Class2 | methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) | public | | | methods3.kt:0:0:0:0 | Methods3Kt | methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) | public, static | | @@ -56,6 +63,8 @@ constructors | delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | | | | delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:6:4:1 | EnumClass | EnumClass(int) | +| enumClass.kt:6:1:16:1 | EnumWithFunctions | enumClass.kt:6:6:16:1 | EnumWithFunctions | EnumWithFunctions() | +| enumClass.kt:8:3:11:4 | VAL | enumClass.kt:8:3:11:4 | VAL | VAL() | | methods2.kt:7:1:10:1 | Class2 | methods2.kt:7:1:10:1 | Class2 | Class2() | | methods3.kt:5:1:7:1 | Class3 | methods3.kt:5:1:7:1 | Class3 | Class3() | | methods4.kt:3:1:11:1 | NestedTest | methods4.kt:3:1:11:1 | NestedTest | NestedTest() | diff --git a/java/ql/test/kotlin/library-tests/methods/parameters.expected b/java/ql/test/kotlin/library-tests/methods/parameters.expected index 7e76cdcb55b..4475aeba459 100644 --- a/java/ql/test/kotlin/library-tests/methods/parameters.expected +++ b/java/ql/test/kotlin/library-tests/methods/parameters.expected @@ -23,6 +23,11 @@ | delegates.kt:8:66:11:5 | invoke | delegates.kt:9:15:9:17 | old | 1 | | delegates.kt:8:66:11:5 | invoke | delegates.kt:9:20:9:22 | new | 2 | | enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:0:0:0:0 | value | 0 | +| enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:0:0:0:0 | value | 0 | +| enumClass.kt:9:14:9:30 | f | enumClass.kt:9:20:9:25 | i | 0 | +| enumClass.kt:10:14:10:42 | g | enumClass.kt:10:20:10:25 | i | 0 | +| enumClass.kt:13:12:13:29 | f | enumClass.kt:13:18:13:23 | i | 0 | +| enumClass.kt:14:12:14:29 | g | enumClass.kt:14:18:14:23 | i | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:26:4:31 | x | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:34:4:39 | y | 1 | | methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:27:8:32 | x | 0 | diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected index ed590470d20..95198f2beaa 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/PrintAst.expected @@ -1165,3 +1165,59 @@ test.kt: # 161| -1: [VarAccess] p0 # 161| 0: [VarAccess] p1 # 161| 1: [VarAccess] p2 +# 165| 15: [Class,GenericType,ParameterizedType] TestGenericUsedWithinDefaultValue +#-----| -2: (Generic Parameters) +# 165| 0: [TypeVariable] T +# 165| 1: [Constructor] TestGenericUsedWithinDefaultValue +# 165| 5: [BlockStmt] { ... } +# 165| 0: [SuperConstructorInvocationStmt] super(...) +# 165| 1: [BlockStmt] { ... } +# 171| 2: [Method] f +# 171| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 171| 0: [Parameter] x +# 171| 0: [TypeAccess] int +# 171| 1: [Parameter] y +# 171| 0: [TypeAccess] String +# 171| 5: [BlockStmt] { ... } +# 171| 3: [Method] f$default +# 171| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 171| 0: [Parameter] p0 +# 171| 0: [TypeAccess] TestGenericUsedWithinDefaultValue<> +# 171| 1: [Parameter] p1 +# 171| 0: [TypeAccess] int +# 171| 2: [Parameter] p2 +# 171| 0: [TypeAccess] String +# 171| 3: [Parameter] p3 +# 171| 0: [TypeAccess] int +# 171| 4: [Parameter] p4 +# 171| 0: [TypeAccess] Object +# 171| 5: [BlockStmt] { ... } +# 171| 0: [IfStmt] if (...) +# 171| 0: [EQExpr] ... == ... +# 171| 0: [AndBitwiseExpr] ... & ... +# 171| 0: [IntegerLiteral] 2 +# 171| 1: [VarAccess] p3 +# 171| 1: [IntegerLiteral] 0 +# 171| 1: [ExprStmt] ; +# 171| 0: [AssignExpr] ...=... +# 171| 0: [VarAccess] p2 +# 171| 1: [MethodAccess] ident(...) +# 171| -1: [ClassInstanceExpr] new TestGenericUsedWithinDefaultValue(...) +# 171| -3: [TypeAccess] TestGenericUsedWithinDefaultValue +# 171| 0: [TypeAccess] String +# 171| 0: [StringLiteral] Hello world +# 171| 1: [ReturnStmt] return ... +# 171| 0: [MethodAccess] f(...) +# 171| -1: [VarAccess] p0 +# 171| 0: [VarAccess] p1 +# 171| 1: [VarAccess] p2 +# 173| 4: [Method] ident +# 173| 3: [TypeAccess] T +#-----| 4: (Parameters) +# 173| 0: [Parameter] t +# 173| 0: [TypeAccess] T +# 173| 5: [BlockStmt] { ... } +# 173| 0: [ReturnStmt] return ... +# 173| 0: [VarAccess] t diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql index b53a83e436c..9bb2ad44c15 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/erasure.ql @@ -1,9 +1,15 @@ import java +class InstantiatedType extends ParameterizedType { + InstantiatedType() { typeArgs(_, _, this) } +} + // This checks that all type parameter references are erased in the context of a $default function. predicate containsTypeVariables(Type t) { - t != t.getErasure() and - not t.getErasure().(GenericType).getRawType() = t + t instanceof TypeVariable or + containsTypeVariables(t.(InstantiatedType).getATypeArgument()) or + containsTypeVariables(t.(NestedType).getEnclosingType()) or + containsTypeVariables(t.(Wildcard).getATypeBound().getType()) } from Expr e diff --git a/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt b/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt index aa8684e8e70..25a29fb468f 100644 --- a/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt +++ b/java/ql/test/kotlin/library-tests/parameter-defaults/test.kt @@ -161,3 +161,15 @@ class VisibilityTests { private fun i(x: Int, y: Int = 0) = x + y } + +class TestGenericUsedWithinDefaultValue { + + // This tests parameter erasure works properly: we should notice that here the type variable T + // isn't used in the specialisation TestGenericUsedWithinDefaultValue, but it can be + // cited in contexts like "the signature of the source declaration of 'TestGenericUsedWithinDefaultValue.f(String)' is 'f(T)'", + // not 'f(Object)' as we might mistakenly conclude if we're inappropriately erasing 'T'. + fun f(x: Int, y: String = TestGenericUsedWithinDefaultValue().ident("Hello world")) { } + + fun ident(t: T) = t + +} diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.qlref b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.qlref new file mode 100644 index 00000000000..6452bb942d2 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposeRepresentation.qlref @@ -0,0 +1 @@ +Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposesRep.kt b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposesRep.kt new file mode 100644 index 00000000000..04d8f8f588d --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/ExposesRep.kt @@ -0,0 +1,3 @@ +class ExposesRep { + val strings: Array = arrayOfNulls(1) +} diff --git a/java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt b/java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt new file mode 100644 index 00000000000..aac812be0d0 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/ExposeRepresentation/User.kt @@ -0,0 +1,5 @@ +class User { + fun test1(er: ExposesRep) { + er.strings[0] = "Hello world" + } +} diff --git a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt index 7e8fa2619e2..f6252b5d3f2 100644 --- a/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt +++ b/java/ql/test/kotlin/query-tests/MissingInstanceofInEquals/Test.kt @@ -5,3 +5,9 @@ data class E(val x: Int) { return (other as? E)?.x == this.x } } + +data class F(val x: Int) { + override fun equals(other: Any?): Boolean { + return other != null && other::class == this::class + } +} diff --git a/java/ql/test/library-tests/frameworks/android/intent/AndroidManifest.xml b/java/ql/test/library-tests/frameworks/android/intent/AndroidManifest.xml index 0be6a0ae8f8..0b7cc21200b 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/AndroidManifest.xml +++ b/java/ql/test/library-tests/frameworks/android/intent/AndroidManifest.xml @@ -18,5 +18,30 @@ android:exported="false"> + + + + + + + + + + + + + + + diff --git a/java/ql/test/library-tests/frameworks/android/intent/TestStartActivityToGetIntent.java b/java/ql/test/library-tests/frameworks/android/intent/TestStartActivityToGetIntent.java index 3d497aac93d..35884a23a58 100644 --- a/java/ql/test/library-tests/frameworks/android/intent/TestStartActivityToGetIntent.java +++ b/java/ql/test/library-tests/frameworks/android/intent/TestStartActivityToGetIntent.java @@ -4,22 +4,90 @@ import android.content.Intent; public class TestStartActivityToGetIntent { - static Object source() { + static Object source(String kind) { return null; } static void sink(Object sink) {} - public void test(Context ctx) { - Intent intent = new Intent(null, SomeActivity.class); - intent.putExtra("data", (String) source()); - ctx.startActivity(intent); + public void test(Context ctx, Activity act) { + + // test all methods that start an activity + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("ctx-start")); + ctx.startActivity(intent); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("ctx-start-acts")); + Intent[] intents = new Intent[] {intent}; + ctx.startActivities(intents); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("act-start")); + act.startActivity(intent); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("act-start-acts")); + Intent[] intents = new Intent[] {intent}; + act.startActivities(intents); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("start-for-result")); + act.startActivityForResult(intent, 0); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("start-if-needed")); + act.startActivityIfNeeded(intent, 0); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("start-matching")); + act.startNextMatchingActivity(intent); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("start-from-child")); + act.startActivityFromChild(null, intent, 0); + } + { + Intent intent = new Intent(null, SomeActivity.class); + intent.putExtra("data", (String) source("start-from-frag")); + act.startActivityFromFragment(null, intent, 0); + } + + // test 4-arg Intent constructor + { + Intent intent = new Intent(null, null, null, SomeActivity.class); + intent.putExtra("data", (String) source("4-arg")); + ctx.startActivity(intent); + } + + // safe test + { + Intent intent = new Intent(null, SafeActivity.class); + intent.putExtra("data", "safe"); + ctx.startActivity(intent); + } } static class SomeActivity extends Activity { public void test() { - sink(getIntent().getStringExtra("data")); // $ hasValueFlow + sink(getIntent().getStringExtra("data")); // $ hasValueFlow=ctx-start hasValueFlow=act-start hasValueFlow=start-for-result hasValueFlow=start-if-needed hasValueFlow=start-matching hasValueFlow=start-from-child hasValueFlow=start-from-frag hasValueFlow=4-arg MISSING: hasValueFlow=ctx-start-acts hasValueFlow=act-start-acts + } + + } + + static class SafeActivity extends Activity { + + public void test() { + sink(getIntent().getStringExtra("data")); // Safe } } } diff --git a/java/ql/test/library-tests/frameworks/android/intent/TestStartBroadcastReceiverToIntent.java b/java/ql/test/library-tests/frameworks/android/intent/TestStartBroadcastReceiverToIntent.java new file mode 100644 index 00000000000..f317b3ed2e8 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/intent/TestStartBroadcastReceiverToIntent.java @@ -0,0 +1,93 @@ +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class TestStartBroadcastReceiverToIntent { + + static Object source(String kind) { + return null; + } + + static void sink(Object sink) {} + + public void test(Context ctx) { + + // test all methods that send a broadcast + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send")); + ctx.sendBroadcast(intent); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-as-user")); + ctx.sendBroadcastAsUser(intent, null); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-with-perm")); + ctx.sendBroadcastWithMultiplePermissions(intent, null); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-ordered")); + ctx.sendOrderedBroadcast(intent, null); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-ordered-as-user")); + ctx.sendOrderedBroadcastAsUser(intent, null, null, null, null, 0, null, null); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-sticky")); + ctx.sendStickyBroadcast(intent); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-sticky-as-user")); + ctx.sendStickyBroadcastAsUser(intent, null); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-sticky-ordered")); + ctx.sendStickyOrderedBroadcast(intent, null, null, 0, null, null); + } + { + Intent intent = new Intent(null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("send-sticky-ordered-as-user")); + ctx.sendStickyOrderedBroadcastAsUser(intent, null, null, null, 0, null, null); + } + + // test 4-arg Intent constructor + { + Intent intent = new Intent(null, null, null, SomeBroadcastReceiver.class); + intent.putExtra("data", (String) source("4-arg")); + ctx.sendBroadcast(intent); + } + + // safe test + { + Intent intent = new Intent(null, SafeBroadcastReceiver.class); + intent.putExtra("data", "safe"); + ctx.sendBroadcast(intent); + } + } + + static class SomeBroadcastReceiver extends BroadcastReceiver { + + // test method that receives an Intent as a parameter + @Override + public void onReceive(Context context, Intent intent) { + sink(intent.getStringExtra("data")); // $ hasValueFlow=send hasValueFlow=send-as-user hasValueFlow=send-with-perm hasValueFlow=send-ordered hasValueFlow=send-ordered-as-user hasValueFlow=send-sticky hasValueFlow=send-sticky-as-user hasValueFlow=send-sticky-ordered hasValueFlow=send-sticky-ordered-as-user hasValueFlow=4-arg + } + } + + static class SafeBroadcastReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + sink(intent.getStringExtra("data")); // Safe + } + } +} diff --git a/java/ql/test/library-tests/frameworks/android/intent/TestStartServiceToIntent.java b/java/ql/test/library-tests/frameworks/android/intent/TestStartServiceToIntent.java new file mode 100644 index 00000000000..98404eed1b7 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/intent/TestStartServiceToIntent.java @@ -0,0 +1,130 @@ +import android.app.Service; +import android.os.IBinder; +import android.content.Context; +import android.content.Intent; + +public class TestStartServiceToIntent { + + static Object source(String kind) { + return null; + } + + static void sink(Object sink) {} + + public void test(Context ctx) { + + // test all methods that start a service + { + Intent intent = new Intent(null, SomeService.class); + intent.putExtra("data", (String) source("bind")); + ctx.bindService(intent, null, 0); + } + { + Intent intent = new Intent(null, SomeService.class); + intent.putExtra("data", (String) source("bind-as-user")); + ctx.bindServiceAsUser(intent, null, 0, null); + } + { + Intent intent = new Intent(null, SomeService.class); + intent.putExtra("data", (String) source("bind-isolated")); + ctx.bindIsolatedService(intent, 0, null, null, null); + } + { + Intent intent = new Intent(null, SomeService.class); + intent.putExtra("data", (String) source("start")); + ctx.startService(intent); + } + { + Intent intent = new Intent(null, SomeService.class); + intent.putExtra("data", (String) source("start-foreground")); + ctx.startForegroundService(intent); + } + + // test 4-arg Intent constructor + { + Intent intent = new Intent(null, null, null, SomeService.class); + intent.putExtra("data", (String) source("4-arg")); + ctx.startService(intent); + } + + // safe test + { + Intent intent = new Intent(null, SafeService.class); + intent.putExtra("data", "safe"); + ctx.startService(intent); + } + } + + static class SomeService extends Service { + + // test methods that receive an Intent as a parameter + @Override + public void onStart(Intent intent, int startId) { + sink(intent.getStringExtra("data")); // $ hasValueFlow=bind hasValueFlow=bind-as-user hasValueFlow=bind-isolated hasValueFlow=start hasValueFlow=start-foreground hasValueFlow=4-arg + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + sink(intent.getStringExtra("data")); // $ hasValueFlow=bind hasValueFlow=bind-as-user hasValueFlow=bind-isolated hasValueFlow=start hasValueFlow=start-foreground hasValueFlow=4-arg + return -1; + } + + @Override + public IBinder onBind(Intent intent) { + sink(intent.getStringExtra("data")); // $ hasValueFlow=bind hasValueFlow=bind-as-user hasValueFlow=bind-isolated hasValueFlow=start hasValueFlow=start-foreground hasValueFlow=4-arg + return null; + } + + @Override + public boolean onUnbind(Intent intent) { + sink(intent.getStringExtra("data")); // $ hasValueFlow=bind hasValueFlow=bind-as-user hasValueFlow=bind-isolated hasValueFlow=start hasValueFlow=start-foreground hasValueFlow=4-arg + return false; + } + + @Override + public void onRebind(Intent intent) { + sink(intent.getStringExtra("data")); // $ hasValueFlow=bind hasValueFlow=bind-as-user hasValueFlow=bind-isolated hasValueFlow=start hasValueFlow=start-foreground hasValueFlow=4-arg + } + + @Override + public void onTaskRemoved(Intent intent) { + sink(intent.getStringExtra("data")); // $ hasValueFlow=bind hasValueFlow=bind-as-user hasValueFlow=bind-isolated hasValueFlow=start hasValueFlow=start-foreground hasValueFlow=4-arg + } + } + + static class SafeService extends Service { + + @Override + public void onStart(Intent intent, int startId) { + sink(intent.getStringExtra("data")); // Safe + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + sink(intent.getStringExtra("data")); // Safe + return -1; + } + + @Override + public IBinder onBind(Intent intent) { + sink(intent.getStringExtra("data")); // Safe + return null; + } + + @Override + public boolean onUnbind(Intent intent) { + sink(intent.getStringExtra("data")); // Safe + return false; + } + + @Override + public void onRebind(Intent intent) { + sink(intent.getStringExtra("data")); // Safe + } + + @Override + public void onTaskRemoved(Intent intent) { + sink(intent.getStringExtra("data")); // Safe + } + } +} diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index d85a14dca02..de3424c2f4d 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.3.1 + +### Minor Analysis Improvements + +- Several of the SQL and NoSQL library models have improved, leading to more results for the `js/sql-injection` query, + and in some cases the `js/missing-rate-limiting` query. + ## 0.3.0 ### Breaking Changes diff --git a/javascript/ql/lib/change-notes/2022-09-06-type-defs-squashed.md b/javascript/ql/lib/change-notes/released/0.3.1.md similarity index 80% rename from javascript/ql/lib/change-notes/2022-09-06-type-defs-squashed.md rename to javascript/ql/lib/change-notes/released/0.3.1.md index 9e628b394dc..81c8ef9fcff 100644 --- a/javascript/ql/lib/change-notes/2022-09-06-type-defs-squashed.md +++ b/javascript/ql/lib/change-notes/released/0.3.1.md @@ -1,6 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.3.1 + +### Minor Analysis Improvements - Several of the SQL and NoSQL library models have improved, leading to more results for the `js/sql-injection` query, and in some cases the `js/missing-rate-limiting` query. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 0cf4b33407a..d5442a13f13 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.3.1-dev +version: 0.3.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 5147bcf7f2a..2e7a9dd4f34 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -711,13 +711,31 @@ module TaintTracking { } } + /** + * Gets a local source of any part of the input to the given stringification `call`. + */ + pragma[nomagic] + private DataFlow::Node getAJsonLocalInput(JsonStringifyCall call) { + result = call.getInput() + or + exists(DataFlow::SourceNode source | + source = pragma[only_bind_out](getAJsonLocalInput(call)).getALocalSource() + | + result = source.getAPropertyWrite().getRhs() + or + result = source.(DataFlow::ObjectLiteralNode).getASpreadProperty() + or + result = source.(DataFlow::ArrayCreationNode).getASpreadArgument() + ) + } + /** * A taint propagating data flow edge arising from JSON unparsing. */ private class JsonStringifyTaintStep extends SharedTaintStep { override predicate serializeStep(DataFlow::Node pred, DataFlow::Node succ) { exists(JsonStringifyCall call | - pred = call.getArgument(0) and + pred = getAJsonLocalInput(call) and succ = call ) } diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index a5e41a1e50a..b166176b56f 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +No user-facing changes. + ## 0.4.0 ### Minor Analysis Improvements diff --git a/javascript/ql/src/change-notes/2022-10-04-json-stringify-improvement.md b/javascript/ql/src/change-notes/2022-10-04-json-stringify-improvement.md new file mode 100644 index 00000000000..0480c231a16 --- /dev/null +++ b/javascript/ql/src/change-notes/2022-10-04-json-stringify-improvement.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improved taint tracking through `JSON.stringify` in cases where a tainted value is stored somewhere in the input object. diff --git a/javascript/ql/src/change-notes/released/0.4.1.md b/javascript/ql/src/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..0d865d0571e --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.4.1.md @@ -0,0 +1,3 @@ +## 0.4.1 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 44ac00e5caf..c3157ce5043 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.4.1-dev +version: 0.4.2-dev groups: - javascript - queries diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 3effc99fcb3..4582ba675a4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -431,6 +431,22 @@ nodes | jquery.js:34:5:34:25 | '' + ... '' | | jquery.js:34:5:34:25 | '' + ... '' | | jquery.js:34:13:34:16 | hash | +| json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | +| json-stringify.jsx:11:51:11:56 | locale | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | +| json-stringify.jsx:19:56:19:61 | locale | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | jwt-server.js:7:9:7:35 | taint | | jwt-server.js:7:9:7:35 | taint | | jwt-server.js:7:17:7:35 | req.param("wobble") | @@ -1509,6 +1525,24 @@ edges | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | @@ -2241,6 +2275,8 @@ edges | jquery.js:27:5:27:25 | hash.re ... #', '') | jquery.js:18:14:18:33 | window.location.hash | jquery.js:27:5:27:25 | hash.re ... #', '') | Cross-site scripting vulnerability due to $@. | jquery.js:18:14:18:33 | window.location.hash | user-provided value | | jquery.js:28:5:28:43 | window. ... ?', '') | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | Cross-site scripting vulnerability due to $@. | jquery.js:28:5:28:26 | window. ... .search | user-provided value | | jquery.js:34:5:34:25 | '' + ... '' | jquery.js:18:14:18:33 | window.location.hash | jquery.js:34:5:34:25 | '' + ... '' | Cross-site scripting vulnerability due to $@. | jquery.js:18:14:18:33 | window.location.hash | user-provided value | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | Cross-site scripting vulnerability due to $@. | json-stringify.jsx:5:18:5:36 | req.param("locale") | user-provided value | +| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | Cross-site scripting vulnerability due to $@. | json-stringify.jsx:5:18:5:36 | req.param("locale") | user-provided value | | jwt-server.js:11:19:11:29 | decoded.foo | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:11:19:11:29 | decoded.foo | Cross-site scripting vulnerability due to $@. | jwt-server.js:7:17:7:35 | req.param("wobble") | user-provided value | | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | HTML injection vulnerability due to $@. | nodemailer.js:13:50:13:66 | req.query.message | user-provided value | | optionalSanitizer.js:6:18:6:23 | target | optionalSanitizer.js:2:16:2:39 | documen ... .search | optionalSanitizer.js:6:18:6:23 | target | Cross-site scripting vulnerability due to $@. | optionalSanitizer.js:2:16:2:39 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index fa65ccbe3df..5c5232b11d2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -431,6 +431,22 @@ nodes | jquery.js:34:5:34:25 | '' + ... '' | | jquery.js:34:5:34:25 | '' + ... '' | | jquery.js:34:13:34:16 | hash | +| json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | +| json-stringify.jsx:11:51:11:56 | locale | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | +| json-stringify.jsx:19:56:19:61 | locale | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | | jwt-server.js:7:9:7:35 | taint | | jwt-server.js:7:9:7:35 | taint | | jwt-server.js:7:17:7:35 | req.param("wobble") | @@ -1559,6 +1575,24 @@ edges | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '' + ... '' | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:5:9:5:36 | locale | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:11:51:11:56 | locale | json-stringify.jsx:11:16:11:58 | `https: ... ocale}` | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | +| json-stringify.jsx:19:56:19:61 | locale | json-stringify.jsx:19:16:19:63 | `https: ... ocale}` | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | +| json-stringify.jsx:31:55:31:60 | locale | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:9:7:35 | taint | jwt-server.js:9:16:9:20 | taint | | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:7:9:7:35 | taint | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/json-stringify.jsx b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/json-stringify.jsx new file mode 100644 index 00000000000..85ad5cef8d4 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/json-stringify.jsx @@ -0,0 +1,42 @@ +var express = require("express"); +var app = express(); + +app.get("/some/path", function (req, res) { + const locale = req.param("locale"); + const breadcrumbList = [ + { + "@type": "ListItem", + position: 1, + item: { + "@id": `https://example.com/some?locale=${locale}`, + name: "Some", + }, + }, + { + "@type": "ListItem", + position: 2, + item: { + "@id": `https://example.com/some/path?locale=${locale}`, + name: "Path", + }, + }, + ]; + const jsonLD = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + itemListElement: breadcrumbList, + }; + // OK +}); diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 6bd73620860..c93557f5801 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.1 + +No user-facing changes. + ## 0.3.0 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.3.1.md b/misc/suite-helpers/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..9fd4efd6c80 --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.3.1.md @@ -0,0 +1,3 @@ +## 0.3.1 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index aa0a2693b1d..0c38110c86a 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.3.1-dev +version: 0.3.2-dev groups: shared diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 962c7b5d023..10707d9d391 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.6.1 + +### Minor Analysis Improvements + +* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects). +* Added modeling of creating Flask responses with `flask.jsonify`. + ## 0.6.0 ### Deprecated APIs diff --git a/python/ql/lib/change-notes/2022-09-22-flask-jsonify.md b/python/ql/lib/change-notes/2022-09-22-flask-jsonify.md deleted file mode 100644 index cac16e270f4..00000000000 --- a/python/ql/lib/change-notes/2022-09-22-flask-jsonify.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added modeling of creating Flask responses with `flask.jsonify`. diff --git a/python/ql/lib/change-notes/2022-09-28-api-subscript.md b/python/ql/lib/change-notes/released/0.6.1.md similarity index 69% rename from python/ql/lib/change-notes/2022-09-28-api-subscript.md rename to python/ql/lib/change-notes/released/0.6.1.md index f14b59d643b..e4ca9748e5f 100644 --- a/python/ql/lib/change-notes/2022-09-28-api-subscript.md +++ b/python/ql/lib/change-notes/released/0.6.1.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.6.1 + +### Minor Analysis Improvements + * Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects). +* Added modeling of creating Flask responses with `flask.jsonify`. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index a3f820f884d..80fb0899f64 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.0 +lastReleaseVersion: 0.6.1 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 6121fdace8c..aea8a2fe067 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.6.1-dev +version: 0.6.2-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index b4f1c73e633..fe091f84e9c 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -344,7 +344,7 @@ module SqlConstruction { * A data-flow node that executes SQL statements. * * If the context of interest is such that merely constructing an SQL statement - * would be valuabe to report, then consider using `SqlConstruction`. + * would be valuable to report, then consider using `SqlConstruction`. * * Extend this class to refine existing API models. If you want to model new APIs, * extend `SqlExecution::Range` instead. @@ -360,7 +360,7 @@ module SqlExecution { * A data-flow node that executes SQL statements. * * If the context of interest is such that merely constructing an SQL statement - * would be valuabe to report, then consider using `SqlConstruction`. + * would be valuable to report, then consider using `SqlConstruction`. * * Extend this class to model new APIs. If you want to refine existing API models, * extend `SqlExecution` instead. @@ -465,7 +465,7 @@ module XML { * A data-flow node that executes a xpath expression. * * If the context of interest is such that merely constructing an XPath expression - * would be valuabe to report, then consider using `XPathConstruction`. + * would be valuable to report, then consider using `XPathConstruction`. * * Extend this class to refine existing API models. If you want to model new APIs, * extend `XPathExecution::Range` instead. @@ -487,7 +487,7 @@ module XML { * A data-flow node that executes a XPath expression. * * If the context of interest is such that merely constructing an XPath expression - * would be valuabe to report, then consider using `XPathConstruction`. + * would be valuable to report, then consider using `XPathConstruction`. * * Extend this class to model new APIs. If you want to refine existing API models, * extend `XPathExecution` instead. 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 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 45e43944ac5..d264b085fc4 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -354,13 +354,7 @@ module Flask { * See https://flask.palletsprojects.com/en/1.1.x/api/#flask.Request */ private class FlaskRequestSource extends RemoteFlowSource::Range { - FlaskRequestSource() { - this = request().getAValueReachableFromSource() and - not any(Import imp).contains(this.asExpr()) and - not exists(ControlFlowNode def | this.asVar().getSourceVariable().hasDefiningNode(def) | - any(Import imp).contains(def.getNode()) - ) - } + FlaskRequestSource() { this = request().asSource() } override string getSourceType() { result = "flask.request" } } diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll index 77c60097cb5..9cf258babe9 100644 --- a/python/ql/lib/semmle/python/frameworks/Tornado.qll +++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll @@ -14,10 +14,12 @@ private import semmle.python.frameworks.Stdlib private import semmle.python.frameworks.internal.InstanceTaintStepsHelper /** + * INTERNAL: Do not use. + * * Provides models for the `tornado` PyPI package. * See https://www.tornadoweb.org/en/stable/. */ -private module Tornado { +module Tornado { /** * Provides models for the `tornado.httputil.HTTPHeaders` class * @@ -126,8 +128,7 @@ private module Tornado { abstract class InstanceSource extends DataFlow::LocalSourceNode { } /** The `self` parameter in a method on the `tornado.web.RequestHandler` class or any subclass. */ - private class SelfParam extends InstanceSource, RemoteFlowSource::Range, - DataFlow::ParameterNode { + class SelfParam extends InstanceSource, RemoteFlowSource::Range, DataFlow::ParameterNode { SelfParam() { exists(RequestHandlerClass cls | cls.getAMethod().getArg(0) = this.getParameter()) } diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index b26aede7b0b..aaf184f4e7c 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.1 + +No user-facing changes. + ## 0.5.0 ### Query Metadata Changes diff --git a/python/ql/src/change-notes/2022-09-29-flask-source-modeling.md b/python/ql/src/change-notes/2022-09-29-flask-source-modeling.md new file mode 100644 index 00000000000..59774242825 --- /dev/null +++ b/python/ql/src/change-notes/2022-09-29-flask-source-modeling.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed how `flask.request` is modeled as a RemoteFlowSource, such that we show fewer duplicated alert messages for Code Scanning alerts. The import, such as `from flask import request`, will now be shown as the first step in a path explanation. diff --git a/python/ql/src/change-notes/released/0.5.1.md b/python/ql/src/change-notes/released/0.5.1.md new file mode 100644 index 00000000000..0275d38f63c --- /dev/null +++ b/python/ql/src/change-notes/released/0.5.1.md @@ -0,0 +1,3 @@ +## 0.5.1 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 30e271c5361..0bf7024c337 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.0 +lastReleaseVersion: 0.5.1 diff --git a/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll b/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll index 21e602e5d34..39b69b10004 100644 --- a/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll +++ b/python/ql/src/experimental/Security/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll @@ -1,73 +1,57 @@ private import python private import semmle.python.Concepts private import semmle.python.ApiGraphs -private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.frameworks.Flask +private import semmle.python.frameworks.Django +private import semmle.python.frameworks.Tornado /** * A data flow source of the client ip obtained according to the remote endpoint identifier specified * (`X-Forwarded-For`, `X-Real-IP`, `Proxy-Client-IP`, etc.) in the header. * * For example: `request.headers.get("X-Forwarded-For")`. + * + * A call to `request.headers.get` or `request.headers.get_all` or `request.headers.getlist`. */ -abstract class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::CallCfgNode { } +abstract class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::Node { } -private class FlaskClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck { +private class FlaskClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck, + DataFlow::MethodCallNode { FlaskClientSuppliedIpUsedInSecurityCheck() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "flask.request" and this.getFunction() = get - | - // `get` is a call to request.headers.get or request.headers.get_all or request.headers.getlist - // request.headers - get.getObject() - .(DataFlow::AttrRead) - // request - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() in ["get", "get_all", "getlist"] and - get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() - ) + this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() } } -private class DjangoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck { +private class DjangoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck, + DataFlow::MethodCallNode { DjangoClientSuppliedIpUsedInSecurityCheck() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "django.http.request.HttpRequest" and this.getFunction() = get - | - // `get` is a call to request.headers.get or request.META.get - // request.headers - get.getObject() - .(DataFlow::AttrRead) - // request - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() = "get" and - get.getObject().(DataFlow::AttrRead).getAttributeName() in ["headers", "META"] and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() - ) + exists(DataFlow::Node req, DataFlow::AttrRead headers | + // a call to request.headers.get or request.META.get + req = PrivateDjango::DjangoImpl::DjangoHttp::Request::HttpRequest::instance() and + headers.getObject().getALocalSource() = req and + headers.getAttributeName() in ["headers", "META"] and + this.calls(headers, "get") + ) and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() } } -private class TornadoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck { +private class TornadoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpUsedInSecurityCheck, + DataFlow::MethodCallNode { TornadoClientSuppliedIpUsedInSecurityCheck() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "tornado.web.RequestHandler" and this.getFunction() = get + // a call to self.request.headers.get or self.request.headers.get_list inside a tornado requesthandler + exists( + Tornado::TornadoModule::Web::RequestHandler::SelfParam selfParam, DataFlow::AttrRead headers, + DataFlow::AttrRead req | - // `get` is a call to `rfs`.request.headers.get - // `rfs`.request.headers - get.getObject() - .(DataFlow::AttrRead) - // `rfs`.request - .getObject() - .(DataFlow::AttrRead) - // `rfs` - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() in ["get", "get_list"] and - get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() - ) + req.getObject().getALocalSource() = selfParam and + req.getAttributeName() = "request" and + headers.getObject().getALocalSource() = req and + headers.getAttributeName() = "headers" and + this.calls(headers, ["get", "get_list"]) + ) and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName() } } diff --git a/python/ql/src/meta/alerts/RemoteFlowSourcesReach.ql b/python/ql/src/meta/alerts/RemoteFlowSourcesReach.ql index b629d1b2955..02e063fd15e 100644 --- a/python/ql/src/meta/alerts/RemoteFlowSourcesReach.ql +++ b/python/ql/src/meta/alerts/RemoteFlowSourcesReach.ql @@ -25,28 +25,15 @@ class RemoteFlowSourceReach extends TaintTracking::Configuration { } override predicate isSink(DataFlow::Node node) { - not node.getLocation().getFile() instanceof IgnoredFile and - ( - node instanceof RemoteFlowSource - or - this.isAdditionalFlowStep(_, node) - ) and - // In september 2021 we changed how we do taint-propagation for method calls (mostly - // relating to modeled frameworks/libraries). We used to do `obj -> obj.meth` and - // `obj.meth -> obj.meth()` in two separate steps, and now do them in one - // `obj -> obj.meth()`. To be able to compare the overall reach between these two - // version, we don't want this query to alert us to the fact that we no longer taint - // the node in the middle (since that is just noise). - // see https://github.com/github/codeql/pull/6349 + not node.getLocation().getFile() instanceof IgnoredFile + // We could try to reduce the number of sinks in this configuration, by only + // allowing something that is on one end of a localFlowStep, readStep or storeStep, + // however, it's a brittle solution that requires us to remember to update this file + // if/when adding something new to the data-flow library. // - // We should be able to remove the following few lines of code once we don't care to - // compare with the old (before September 2021) way of doing taint-propagation for - // method calls. - not exists(DataFlow::MethodCallNode c | - node = c.getFunction() and - this.isAdditionalFlowStep(c.getObject(), node) and - this.isAdditionalFlowStep(node, c) - ) + // From testing on a few projects, trying to reduce the number of nodes, we only + // gain a reduction in the range of 40%, and while that's nice, it doesn't seem + // worth it to me for a meta query. } } diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 6e3e2010677..31b6ab69f2e 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.5.1-dev +version: 0.5.2-dev groups: - python - queries diff --git a/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected index f787dfa43fc..77dafce4a10 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-079/ReflectedXSS.expected @@ -1,4 +1,9 @@ edges +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | flask_mail.py:13:22:13:28 | ControlFlowNode for request | +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | flask_mail.py:18:14:18:20 | ControlFlowNode for request | +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | flask_mail.py:31:24:31:30 | ControlFlowNode for request | +| flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:1:19:1:25 | GSSA Variable request | +| flask_mail.py:1:19:1:25 | GSSA Variable request | flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute | | flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | @@ -6,6 +11,11 @@ edges | flask_mail.py:18:14:18:25 | ControlFlowNode for Attribute | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | | flask_mail.py:31:24:31:30 | ControlFlowNode for request | flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | | flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | +| sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:1:19:1:25 | GSSA Variable request | +| sendgrid_mail.py:1:19:1:25 | GSSA Variable request | sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | | sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:34:26:45 | ControlFlowNode for Attribute | @@ -13,6 +23,11 @@ edges | sendgrid_mail.py:26:34:26:61 | ControlFlowNode for Subscript | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute | | sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | +| sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | +| sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:62 | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:61 | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | @@ -25,9 +40,15 @@ edges | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | +| smtplib_bad_subparts.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_subparts.request | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | +| smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_subparts.py:2:26:2:32 | GSSA Variable request | +| smtplib_bad_subparts.py:2:26:2:32 | GSSA Variable request | smtplib_bad_subparts.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_subparts.request | | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | | smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | | smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | +| smtplib_bad_via_attach.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_via_attach.request | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | +| smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_via_attach.py:2:26:2:32 | GSSA Variable request | +| smtplib_bad_via_attach.py:2:26:2:32 | GSSA Variable request | smtplib_bad_via_attach.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_via_attach.request | | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | | smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | | smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | @@ -35,6 +56,9 @@ nodes | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| flask_mail.py:0:0:0:0 | ModuleVariableNode for flask_mail.request | semmle.label | ModuleVariableNode for flask_mail.request | +| flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_mail.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_mail.py:13:22:13:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_mail.py:13:22:13:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -44,6 +68,9 @@ nodes | flask_mail.py:31:24:31:30 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_mail.py:31:24:31:35 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| sendgrid_mail.py:0:0:0:0 | ModuleVariableNode for sendgrid_mail.request | semmle.label | ModuleVariableNode for sendgrid_mail.request | +| sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| sendgrid_mail.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_mail.py:14:22:14:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -54,6 +81,9 @@ nodes | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_mail.py:37:41:37:52 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| sendgrid_via_mail_send_post_request_body_bad.py:0:0:0:0 | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | semmle.label | ModuleVariableNode for sendgrid_via_mail_send_post_request_body_bad.request | +| sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | GSSA Variable request | semmle.label | GSSA Variable request | | sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:62 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -66,10 +96,16 @@ nodes | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:61 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:78 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| smtplib_bad_subparts.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_subparts.request | semmle.label | ModuleVariableNode for smtplib_bad_subparts.request | +| smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| smtplib_bad_subparts.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | smtplib_bad_subparts.py:17:12:17:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | smtplib_bad_subparts.py:17:12:17:33 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | semmle.label | ControlFlowNode for html | +| smtplib_bad_via_attach.py:0:0:0:0 | ModuleVariableNode for smtplib_bad_via_attach.request | semmle.label | ModuleVariableNode for smtplib_bad_via_attach.request | +| smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| smtplib_bad_via_attach.py:2:26:2:32 | GSSA Variable request | semmle.label | GSSA Variable request | | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | smtplib_bad_via_attach.py:20:12:20:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | smtplib_bad_via_attach.py:20:12:20:31 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -79,18 +115,14 @@ subpaths | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:14:48:14:82 | ControlFlowNode for Attribute() | a user-provided value | | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:23:30:23:64 | ControlFlowNode for Attribute() | a user-provided value | | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | django_mail.py:25:32:25:66 | ControlFlowNode for Attribute() | a user-provided value | -| flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:13:22:13:28 | ControlFlowNode for request | a user-provided value | -| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:13:22:13:28 | ControlFlowNode for request | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:13:22:13:28 | ControlFlowNode for request | a user-provided value | -| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:18:14:18:20 | ControlFlowNode for request | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:18:14:18:20 | ControlFlowNode for request | a user-provided value | -| flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | flask_mail.py:31:24:31:30 | ControlFlowNode for request | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:31:24:31:30 | ControlFlowNode for request | a user-provided value | -| sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:14:22:14:28 | ControlFlowNode for request | a user-provided value | -| sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:26:34:26:40 | ControlFlowNode for request | a user-provided value | -| sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:37:41:37:47 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:16:51:16:57 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:27:50:27:56 | ControlFlowNode for request | a user-provided value | -| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:41:50:41:56 | ControlFlowNode for request | a user-provided value | -| smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_subparts.py:17:12:17:18 | ControlFlowNode for request | a user-provided value | -| smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_via_attach.py:20:12:20:18 | ControlFlowNode for request | a user-provided value | +| flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:13:22:13:41 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:18:14:18:33 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | flask_mail.py:31:24:31:43 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | flask_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:14:22:14:49 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:26:22:26:62 | ControlFlowNode for HtmlContent() | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | sendgrid_mail.py:37:41:37:68 | ControlFlowNode for Subscript | Cross-site scripting vulnerability due to $@. | sendgrid_mail.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | sendgrid_via_mail_send_post_request_body_bad.py:16:26:16:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | sendgrid_via_mail_send_post_request_body_bad.py:27:25:27:77 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | a user-provided value | +| sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | sendgrid_via_mail_send_post_request_body_bad.py:41:25:41:79 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | sendgrid_via_mail_send_post_request_body_bad.py:3:19:3:25 | ControlFlowNode for ImportMember | a user-provided value | +| smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_subparts.py:24:22:24:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_subparts.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | +| smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | smtplib_bad_via_attach.py:27:22:27:25 | ControlFlowNode for html | Cross-site scripting vulnerability due to $@. | smtplib_bad_via_attach.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected index 100beb0f4b3..588c9ea3bb5 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-113/HeaderInjection.expected @@ -1,6 +1,12 @@ edges | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:9:18:9:24 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:19:18:19:24 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:27:18:27:24 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:35:18:35:24 | ControlFlowNode for request | +| flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:1:29:1:35 | GSSA Variable request | +| flask_bad.py:1:29:1:35 | GSSA Variable request | flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | | flask_bad.py:9:18:9:24 | ControlFlowNode for request | flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | | flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | | flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | @@ -18,6 +24,9 @@ nodes | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header | | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | semmle.label | ModuleVariableNode for flask_bad.request | +| flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_bad.py:1:29:1:35 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_bad.py:9:18:9:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_bad.py:9:18:9:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_bad.py:9:18:9:43 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -38,7 +47,7 @@ subpaths #select | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | django_bad.py:7:40:7:49 | ControlFlowNode for rfs_header | This | django_bad.py:5:18:5:58 | ControlFlowNode for Attribute() | user-provided value | | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | django_bad.py:14:30:14:39 | ControlFlowNode for rfs_header | This | django_bad.py:12:18:12:58 | ControlFlowNode for Attribute() | user-provided value | -| flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | flask_bad.py:9:18:9:24 | ControlFlowNode for request | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | This | flask_bad.py:9:18:9:24 | ControlFlowNode for request | user-provided value | -| flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | flask_bad.py:19:18:19:24 | ControlFlowNode for request | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | This | flask_bad.py:19:18:19:24 | ControlFlowNode for request | user-provided value | -| flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | flask_bad.py:27:18:27:24 | ControlFlowNode for request | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | This | flask_bad.py:27:18:27:24 | ControlFlowNode for request | user-provided value | -| flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | flask_bad.py:35:18:35:24 | ControlFlowNode for request | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | This | flask_bad.py:35:18:35:24 | ControlFlowNode for request | user-provided value | +| flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:12:31:12:40 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | +| flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:21:38:21:47 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | +| flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:29:34:29:43 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | +| flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | $@ HTTP header is constructed from a $@. | flask_bad.py:38:24:38:33 | ControlFlowNode for rfs_header | This | flask_bad.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | 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 2b6fb18f47b..5b6b8a4bc24 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 @@ -1,10 +1,17 @@ edges +| csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.request | csv_bad.py:16:16:16:22 | ControlFlowNode for request | +| csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.request | csv_bad.py:24:16:24:22 | ControlFlowNode for request | +| csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:9:19:9:25 | GSSA Variable request | +| csv_bad.py:9:19:9:25 | GSSA Variable request | csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.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: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 | nodes +| csv_bad.py:0:0:0:0 | ModuleVariableNode for csv_bad.request | semmle.label | ModuleVariableNode for csv_bad.request | +| 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:18:24:18:31 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | @@ -14,6 +21,6 @@ nodes | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | semmle.label | ControlFlowNode for csv_data | subpaths #select -| csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | csv_bad.py:16:16:16:22 | ControlFlowNode for request | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:16:16:16:22 | ControlFlowNode for request | this user input | -| csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | csv_bad.py:16:16:16:22 | ControlFlowNode for request | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:16:16:16:22 | ControlFlowNode for request | this user input | -| csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | csv_bad.py:24:16:24:22 | ControlFlowNode for request | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:24:16:24:22 | ControlFlowNode for request | this user input | +| csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:18:24:18:31 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | +| csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:19:25:19:32 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | +| csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | csv_bad.py:25:46:25:53 | ControlFlowNode for csv_data | Csv injection might include code from $@. | csv_bad.py:9:19:9:25 | ControlFlowNode for ImportMember | this user input | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected index 24784f039e7..425b00a85c7 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-522/LDAPInsecureAuth.expected @@ -1,4 +1,7 @@ edges +| ldap3_remote.py:0:0:0:0 | ModuleVariableNode for ldap3_remote.request | ldap3_remote.py:138:21:138:27 | ControlFlowNode for request | +| ldap3_remote.py:2:19:2:25 | ControlFlowNode for ImportMember | ldap3_remote.py:2:19:2:25 | GSSA Variable request | +| ldap3_remote.py:2:19:2:25 | GSSA Variable request | ldap3_remote.py:0:0:0:0 | ModuleVariableNode for ldap3_remote.request | | ldap3_remote.py:101:12:101:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | | ldap3_remote.py:114:12:114:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | | ldap3_remote.py:126:12:126:31 | ControlFlowNode for BinaryExpr | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | @@ -8,6 +11,9 @@ edges nodes | ldap2_remote.py:45:41:45:60 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | ldap2_remote.py:56:41:56:60 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| ldap3_remote.py:0:0:0:0 | ModuleVariableNode for ldap3_remote.request | semmle.label | ModuleVariableNode for ldap3_remote.request | +| ldap3_remote.py:2:19:2:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap3_remote.py:2:19:2:25 | GSSA Variable request | semmle.label | GSSA Variable request | | ldap3_remote.py:101:12:101:49 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | semmle.label | ControlFlowNode for host | | ldap3_remote.py:114:12:114:49 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | @@ -25,4 +31,4 @@ subpaths | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | ldap3_remote.py:101:12:101:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:102:18:102:21 | ControlFlowNode for host | This LDAP host | | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | ldap3_remote.py:114:12:114:49 | ControlFlowNode for BinaryExpr | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:115:18:115:21 | ControlFlowNode for host | This LDAP host | | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | ldap3_remote.py:126:12:126:31 | ControlFlowNode for BinaryExpr | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:127:18:127:21 | ControlFlowNode for host | This LDAP host | -| ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | ldap3_remote.py:138:21:138:27 | ControlFlowNode for request | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | This LDAP host | +| ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | ldap3_remote.py:2:19:2:25 | ControlFlowNode for ImportMember | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | $@ is authenticated insecurely. | ldap3_remote.py:139:18:139:21 | ControlFlowNode for host | This LDAP host | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected index d246f8b14d6..5cc54fbdad2 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-614/CookieInjection.expected @@ -1,6 +1,12 @@ edges | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:24:21:24:27 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:24:49:24:55 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:32:37:32:43 | ControlFlowNode for request | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | flask_bad.py:32:60:32:66 | ControlFlowNode for request | +| flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:1:26:1:32 | GSSA Variable request | +| flask_bad.py:1:26:1:32 | GSSA Variable request | flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:32 | ControlFlowNode for Attribute | | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:60 | ControlFlowNode for Attribute | | flask_bad.py:24:21:24:32 | ControlFlowNode for Attribute | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | @@ -19,6 +25,9 @@ nodes | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| flask_bad.py:0:0:0:0 | ModuleVariableNode for flask_bad.request | semmle.label | ModuleVariableNode for flask_bad.request | +| flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_bad.py:24:21:24:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_bad.py:24:21:24:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -46,18 +55,12 @@ subpaths | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input | | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input | | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input | -| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:24:21:24:27 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:49:24:55 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:24:49:24:55 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:49:24:55 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:24:49:24:55 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:24:49:24:55 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:24:49:24:55 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:37:32:43 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:32:37:32:43 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:37:32:43 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:32:37:32:43 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:37:32:43 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:32:37:32:43 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:60:32:66 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:32:60:32:66 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:60:32:66 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:32:60:32:66 | ControlFlowNode for request | user-supplied input | -| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:32:60:32:66 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:32:60:32:66 | ControlFlowNode for request | user-supplied input | +| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | +| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected index 2922cc9f97e..54948a2d17f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-943/NoSQLInjection.expected @@ -1,4 +1,8 @@ edges +| flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | +| flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | +| flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_mongoengine_bad.py:1:26:1:32 | GSSA Variable request | +| flask_mongoengine_bad.py:1:26:1:32 | GSSA Variable request | flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | | flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | | flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:20:30:20:42 | ControlFlowNode for unsafe_search | @@ -9,11 +13,22 @@ edges | flask_mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | +| flask_pymongo_bad.py:0:0:0:0 | ModuleVariableNode for flask_pymongo_bad.request | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | +| flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_pymongo_bad.py:1:26:1:32 | GSSA Variable request | +| flask_pymongo_bad.py:1:26:1:32 | GSSA Variable request | flask_pymongo_bad.py:0:0:0:0 | ModuleVariableNode for flask_pymongo_bad.request | | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | | flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | | flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | +| mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:1:26:1:32 | GSSA Variable request | +| mongoengine_bad.py:1:26:1:32 | GSSA Variable request | mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | | mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | | mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | mongoengine_bad.py:19:30:19:42 | ControlFlowNode for unsafe_search | @@ -44,6 +59,11 @@ edges | mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | +| pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:1:26:1:32 | GSSA Variable request | +| pymongo_test.py:1:26:1:32 | GSSA Variable request | pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | pymongo_test.py:12:21:12:32 | ControlFlowNode for Attribute | | pymongo_test.py:12:21:12:32 | ControlFlowNode for Attribute | pymongo_test.py:12:21:12:42 | ControlFlowNode for Subscript | | pymongo_test.py:12:21:12:42 | ControlFlowNode for Subscript | pymongo_test.py:13:30:13:42 | ControlFlowNode for unsafe_search | @@ -58,6 +78,9 @@ edges | pymongo_test.py:39:27:39:38 | ControlFlowNode for Attribute | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | | pymongo_test.py:39:27:39:50 | ControlFlowNode for Subscript | pymongo_test.py:39:16:39:51 | ControlFlowNode for Attribute() | nodes +| flask_mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for flask_mongoengine_bad.request | semmle.label | ModuleVariableNode for flask_mongoengine_bad.request | +| flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_mongoengine_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -70,12 +93,18 @@ nodes | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_mongoengine_bad.py:27:30:27:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| flask_pymongo_bad.py:0:0:0:0 | ModuleVariableNode for flask_pymongo_bad.request | semmle.label | ModuleVariableNode for flask_pymongo_bad.request | +| flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| flask_pymongo_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | flask_pymongo_bad.py:12:30:12:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| mongoengine_bad.py:0:0:0:0 | ModuleVariableNode for mongoengine_bad.request | semmle.label | ModuleVariableNode for mongoengine_bad.request | +| mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| mongoengine_bad.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -112,6 +141,9 @@ nodes | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | mongoengine_bad.py:58:30:58:42 | ControlFlowNode for unsafe_search | semmle.label | ControlFlowNode for unsafe_search | | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | +| pymongo_test.py:0:0:0:0 | ModuleVariableNode for pymongo_test.request | semmle.label | ModuleVariableNode for pymongo_test.request | +| pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| pymongo_test.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | pymongo_test.py:12:21:12:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | pymongo_test.py:12:21:12:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -130,15 +162,15 @@ nodes | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict | subpaths #select -| flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | This | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | user-provided value | -| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | This | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | user-provided value | -| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | This | flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | This | mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | user-provided value | -| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | This | mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | user-provided value | -| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | This | pymongo_test.py:12:21:12:27 | ControlFlowNode for request | user-provided value | -| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | This | pymongo_test.py:29:27:29:33 | ControlFlowNode for request | user-provided value | -| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | This | pymongo_test.py:39:27:39:33 | ControlFlowNode for request | user-provided value | +| flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | This | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | This | flask_mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | This | flask_pymongo_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | This | mongoengine_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:15:42:15:62 | ControlFlowNode for Dict | This | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:33:34:33:73 | ControlFlowNode for Dict | This | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | +| pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | pymongo_test.py:43:34:43:73 | ControlFlowNode for Dict | This | pymongo_test.py:1:26:1:32 | ControlFlowNode for ImportMember | user-provided value | 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 fcb2d3103eb..c64a6943813 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,10 +1,16 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:13:16:13:22 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for test.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 | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| 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 | subpaths #select -| test.py:15:36:15:39 | ControlFlowNode for data | test.py:13:16:13:22 | ControlFlowNode for request | test.py:15:36:15:39 | ControlFlowNode for data | Call to hmac.new [param 1] with untrusted data from $@. | test.py:13:16:13:22 | ControlFlowNode for request | ControlFlowNode for request | +| 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 [param 1] 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 49c173f6fe9..64fe441dc64 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,6 +1,22 @@ edges +| flask_path_injection.py:0:0:0:0 | ModuleVariableNode for flask_path_injection.request | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for flask_path_injection.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:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:12:16:12:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:19:16:19:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:27:16:27:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:46:16:46:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:63:16:63:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:84:16:84:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:107:16:107:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:118:16:118:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:129:16:129:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:138:16:138:22 | ControlFlowNode for request | +| path_injection.py:0:0:0:0 | ModuleVariableNode for path_injection.request | path_injection.py:149:16:149:22 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for path_injection.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 | @@ -33,6 +49,9 @@ edges | 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 | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:9:12:9:18 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for test.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() | @@ -52,9 +71,15 @@ edges | 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:0:0:0:0 | ModuleVariableNode for flask_path_injection.request | semmle.label | ModuleVariableNode for flask_path_injection.request | +| 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:0:0:0:0 | ModuleVariableNode for path_injection.request | semmle.label | ModuleVariableNode for path_injection.request | +| 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() | @@ -100,6 +125,9 @@ nodes | 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 | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| 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() | @@ -122,21 +150,21 @@ 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:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | This path depends on $@. | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | a user-provided value | -| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | This path depends on $@. | path_injection.py:12:16:12:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:21:14:21:18 | ControlFlowNode for npath | path_injection.py:19:16:19:22 | ControlFlowNode for request | path_injection.py:21:14:21:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:19:16:19:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:31:14:31:18 | ControlFlowNode for npath | path_injection.py:27:16:27:22 | ControlFlowNode for request | path_injection.py:31:14:31:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:27:16:27:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:48:14:48:18 | ControlFlowNode for npath | path_injection.py:46:16:46:22 | ControlFlowNode for request | path_injection.py:48:14:48:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:46:16:46:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:65:14:65:18 | ControlFlowNode for npath | path_injection.py:63:16:63:22 | ControlFlowNode for request | path_injection.py:65:14:65:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:63:16:63:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | This path depends on $@. | path_injection.py:84:16:84:22 | ControlFlowNode for request | a user-provided value | +| 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 $@. | flask_path_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | a 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 $@. | path_injection.py:98:20:98:22 | ControlFlowNode for foo | a user-provided value | -| path_injection.py:113:14:113:17 | ControlFlowNode for path | path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:113:14:113:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:107:16:107:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:124:14:124:17 | ControlFlowNode for path | path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:124:14:124:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:118:16:118:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | This path depends on $@. | path_injection.py:129:16:129:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:142:14:142:17 | ControlFlowNode for path | path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:142:14:142:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:138:16:138:22 | ControlFlowNode for request | a user-provided value | -| path_injection.py:152:18:152:21 | ControlFlowNode for path | path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:152:18:152:21 | ControlFlowNode for path | This path depends on $@. | path_injection.py:149:16:149:22 | ControlFlowNode for request | a user-provided value | -| test.py:19:10:19:10 | ControlFlowNode for x | test.py:9:12:9:18 | ControlFlowNode for request | test.py:19:10:19:10 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value | -| test.py:26:10:26:10 | ControlFlowNode for y | test.py:9:12:9:18 | ControlFlowNode for request | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value | -| test.py:33:14:33:14 | ControlFlowNode for x | test.py:9:12:9:18 | ControlFlowNode for request | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value | -| test.py:49:14:49:14 | ControlFlowNode for y | test.py:9:12:9:18 | ControlFlowNode for request | test.py:49:14:49:14 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | path_injection.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:3:26:3:32 | ControlFlowNode for ImportMember | a user-provided value | 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 8d26b3f6d5c..c86a2a28688 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,7 @@ edges +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:18:13:18:19 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for command_injection.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 | @@ -10,6 +13,9 @@ edges | 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:0:0:0:0 | ModuleVariableNode for command_injection.request | semmle.label | ModuleVariableNode for command_injection.request | +| 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 | @@ -23,12 +29,12 @@ nodes | 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:18:13:18:19 | ControlFlowNode for request | command_injection.py:19:15:19:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:20:15:20:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:21:15:21:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:23:20:23:32 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:25:19:25:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:26:19:26:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:27:19:27:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:28:19:28:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:29:19:29:31 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | +| 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 cce39a976db..71b8d19b2cd 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,14 @@ edges +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:11:13:11:19 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:18:13:18:19 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:25:11:25:17 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:31:13:31:19 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:38:15:38:21 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:54:15:54:21 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:71:12:71:18 | ControlFlowNode for request | +| command_injection.py:0:0:0:0 | ModuleVariableNode for command_injection.request | command_injection.py:78:12:78:18 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for command_injection.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 | @@ -21,6 +31,9 @@ edges | 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:0:0:0:0 | ModuleVariableNode for command_injection.request | semmle.label | ModuleVariableNode for command_injection.request | +| 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 | @@ -52,16 +65,16 @@ nodes | 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:11:13:11:19 | ControlFlowNode for request | command_injection.py:13:15:13:27 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:11:13:11:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | command_injection.py:18:13:18:19 | ControlFlowNode for request | command_injection.py:20:22:20:34 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:18:13:18:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:26:23:26:25 | ControlFlowNode for cmd | command_injection.py:25:11:25:17 | ControlFlowNode for request | command_injection.py:26:23:26:25 | ControlFlowNode for cmd | This command line depends on $@. | command_injection.py:25:11:25:17 | ControlFlowNode for request | a user-provided value | -| command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | command_injection.py:31:13:31:19 | ControlFlowNode for request | command_injection.py:33:14:33:26 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:31:13:31:19 | ControlFlowNode for request | a user-provided value | -| command_injection.py:41:15:41:21 | ControlFlowNode for command | command_injection.py:38:15:38:21 | ControlFlowNode for request | command_injection.py:41:15:41:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:38:15:38:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:42:15:42:21 | ControlFlowNode for command | command_injection.py:38:15:38:21 | ControlFlowNode for request | command_injection.py:42:15:42:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:38:15:38:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:55:15:55:21 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:55:15:55:21 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:56:14:56:20 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:56:14:56:20 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:57:21:57:27 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:57:21:57:27 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:58:27:58:33 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:58:27:58:33 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:59:20:59:26 | ControlFlowNode for command | command_injection.py:54:15:54:21 | ControlFlowNode for request | command_injection.py:59:20:59:26 | ControlFlowNode for command | This command line depends on $@. | command_injection.py:54:15:54:21 | ControlFlowNode for request | a user-provided value | -| command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | command_injection.py:71:12:71:18 | ControlFlowNode for request | command_injection.py:73:19:73:30 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:71:12:71:18 | ControlFlowNode for request | a user-provided value | -| command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | command_injection.py:78:12:78:18 | ControlFlowNode for request | command_injection.py:80:19:80:30 | ControlFlowNode for BinaryExpr | This command line depends on $@. | command_injection.py:78:12:78:18 | ControlFlowNode for request | a user-provided value | +| 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a 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 $@. | command_injection.py:5:26:5:32 | ControlFlowNode for ImportMember | a user-provided value | 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 39c2bb3778f..5dc0fc3e5d7 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,4 +1,9 @@ edges +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for reflected_xss.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 | @@ -6,6 +11,9 @@ edges | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | reflected_xss.py:27:23:27:34 | ControlFlowNode for Attribute | | reflected_xss.py:27:23:27:34 | ControlFlowNode for Attribute | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | nodes +| reflected_xss.py:0:0:0:0 | ModuleVariableNode for reflected_xss.request | semmle.label | ModuleVariableNode for reflected_xss.request | +| 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 | @@ -17,6 +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:9:18:9:24 | ControlFlowNode for request | reflected_xss.py:10:26:10:53 | ControlFlowNode for BinaryExpr | Cross-site scripting vulnerability due to $@. | reflected_xss.py:9:18:9:24 | ControlFlowNode for request | a user-provided value | -| reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | reflected_xss.py:22:26:22:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | reflected_xss.py:21:23:21:29 | ControlFlowNode for request | a user-provided value | -| reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | reflected_xss.py:28:26:28:41 | ControlFlowNode for Attribute() | Cross-site scripting vulnerability due to $@. | reflected_xss.py:27:23:27:29 | ControlFlowNode for request | a user-provided value | +| 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 $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | a 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 $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | a 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 $@. | reflected_xss.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected index 7dcddaaae83..53fd7478f44 100644 --- a/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-090-LdapInjection/LdapInjection.expected @@ -1,4 +1,14 @@ edges +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:14:21:14:27 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:1:19:1:25 | GSSA Variable request | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:1:19:1:25 | GSSA Variable request | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:13:17:13:28 | ControlFlowNode for Attribute | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:14:21:14:32 | ControlFlowNode for Attribute | | ldap3_bad.py:13:17:13:28 | ControlFlowNode for Attribute | ldap3_bad.py:13:17:13:34 | ControlFlowNode for Subscript | @@ -13,6 +23,19 @@ edges | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | ldap3_bad.py:31:21:31:32 | ControlFlowNode for Attribute | | ldap3_bad.py:31:21:31:32 | ControlFlowNode for Attribute | ldap3_bad.py:31:21:31:44 | ControlFlowNode for Subscript | | ldap3_bad.py:31:21:31:44 | ControlFlowNode for Subscript | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:14:21:14:27 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:31:21:31:27 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | ldap_bad.py:48:21:48:27 | ControlFlowNode for request | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:1:19:1:25 | GSSA Variable request | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:1:19:1:25 | GSSA Variable request | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:13:17:13:28 | ControlFlowNode for Attribute | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:14:21:14:32 | ControlFlowNode for Attribute | | ldap_bad.py:13:17:13:28 | ControlFlowNode for Attribute | ldap_bad.py:13:17:13:34 | ControlFlowNode for Subscript | @@ -35,6 +58,12 @@ edges | ldap_bad.py:48:21:48:32 | ControlFlowNode for Attribute | ldap_bad.py:48:21:48:44 | ControlFlowNode for Subscript | | ldap_bad.py:48:21:48:44 | ControlFlowNode for Subscript | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | nodes +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | semmle.label | ModuleVariableNode for ldap3_bad.request | +| ldap3_bad.py:0:0:0:0 | ModuleVariableNode for ldap3_bad.request | semmle.label | ModuleVariableNode for ldap3_bad.request | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| ldap3_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap3_bad.py:13:17:13:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -53,6 +82,12 @@ nodes | ldap3_bad.py:31:21:31:44 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | semmle.label | ControlFlowNode for dn | | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | semmle.label | ControlFlowNode for search_filter | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | semmle.label | ModuleVariableNode for ldap_bad.request | +| ldap_bad.py:0:0:0:0 | ModuleVariableNode for ldap_bad.request | semmle.label | ModuleVariableNode for ldap_bad.request | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| ldap_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | ldap_bad.py:13:17:13:28 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -82,18 +117,13 @@ nodes | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | semmle.label | ControlFlowNode for search_filter | subpaths #select -| ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | ldap3_bad.py:14:21:14:27 | ControlFlowNode for request | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:14:21:14:27 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:31:21:31:27 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:13:17:13:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | ldap_bad.py:14:21:14:27 | ControlFlowNode for request | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:14:21:14:27 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | ldap_bad.py:31:21:31:27 | ControlFlowNode for request | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:31:21:31:27 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:47:17:47:23 | ControlFlowNode for request | a user-provided value | -| ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | ldap_bad.py:48:21:48:27 | ControlFlowNode for request | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:48:21:48:27 | ControlFlowNode for request | a user-provided value | +| ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:21:17:21:18 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:21:21:21:33 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | $@ depends on $@. | ldap3_bad.py:38:9:38:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | $@ depends on $@. | ldap3_bad.py:38:13:38:25 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap3_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:21:9:21:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:21:33:21:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:37:9:37:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:37:33:37:45 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | $@ depends on $@. | ldap_bad.py:55:9:55:10 | ControlFlowNode for dn | LDAP query parameter (DN) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | $@ depends on $@. | ldap_bad.py:55:43:55:55 | ControlFlowNode for search_filter | LDAP query parameter (filter) | ldap_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a 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 97f5bc54118..a1911a6331e 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,8 @@ edges +| code_injection.py:0:0:0:0 | ModuleVariableNode for code_injection.request | code_injection.py:6:12:6:18 | ControlFlowNode for request | +| code_injection.py:0:0:0:0 | ModuleVariableNode for code_injection.request | code_injection.py:18:16:18:22 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for code_injection.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 | @@ -6,6 +10,9 @@ edges | 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:0:0:0:0 | ModuleVariableNode for code_injection.request | semmle.label | ModuleVariableNode for code_injection.request | +| 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 | @@ -16,7 +23,7 @@ nodes | 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:6:12:6:18 | ControlFlowNode for request | code_injection.py:7:10:7:13 | ControlFlowNode for code | This code execution depends on $@. | code_injection.py:6:12:6:18 | ControlFlowNode for request | a user-provided value | -| code_injection.py:8:10:8:13 | ControlFlowNode for code | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:8:10:8:13 | ControlFlowNode for code | This code execution depends on $@. | code_injection.py:6:12:6:18 | ControlFlowNode for request | a user-provided value | -| code_injection.py:10:10:10:12 | ControlFlowNode for cmd | code_injection.py:6:12:6:18 | ControlFlowNode for request | code_injection.py:10:10:10:12 | ControlFlowNode for cmd | This code execution depends on $@. | code_injection.py:6:12:6:18 | ControlFlowNode for request | a user-provided value | -| code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | code_injection.py:18:16:18:22 | ControlFlowNode for request | code_injection.py:21:20:21:27 | ControlFlowNode for obj_name | This code execution depends on $@. | code_injection.py:18:16:18:22 | ControlFlowNode for request | a user-provided value | +| 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 $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | code_injection.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 9641f49e3e2..d4138316fc2 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,10 @@ edges +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | +| LogInjectionBad.py:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for LogInjectionBad.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 | @@ -8,6 +14,9 @@ edges | 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:0:0:0:0 | ModuleVariableNode for LogInjectionBad.request | semmle.label | ModuleVariableNode for LogInjectionBad.request | +| 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 | @@ -22,7 +31,7 @@ nodes | 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:17:12:17:18 | ControlFlowNode for request | LogInjectionBad.py:18:21:18:40 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:17:12:17:18 | ControlFlowNode for request | a user-provided value | -| LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | LogInjectionBad.py:24:18:24:37 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:23:12:23:18 | ControlFlowNode for request | a user-provided value | -| LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | LogInjectionBad.py:30:25:30:44 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:29:12:29:18 | ControlFlowNode for request | a user-provided value | -| LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | LogInjectionBad.py:37:19:37:38 | ControlFlowNode for BinaryExpr | This log entry depends on $@. | LogInjectionBad.py:35:12:35:18 | ControlFlowNode for request | a user-provided value | +| 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 $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a 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 $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a 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 $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a 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 $@. | LogInjectionBad.py:7:19:7:25 | ControlFlowNode for ImportMember | a 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 9cab4ce7d16..dc536fa9e7e 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,10 +1,16 @@ edges +| unsafe_deserialization.py:0:0:0:0 | ModuleVariableNode for unsafe_deserialization.request | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for unsafe_deserialization.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:0:0:0:0 | ModuleVariableNode for unsafe_deserialization.request | semmle.label | ModuleVariableNode for unsafe_deserialization.request | +| 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 | @@ -13,7 +19,7 @@ nodes | 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:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:15:18:15:24 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | -| unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:16:15:16:21 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | -| unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:18:19:18:25 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | -| unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | unsafe_deserialization.py:21:16:21:22 | ControlFlowNode for payload | Unsafe deserialization depends on $@. | unsafe_deserialization.py:14:15:14:21 | ControlFlowNode for request | a user-provided value | +| 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 $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a 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 $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a 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 $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a 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 $@. | unsafe_deserialization.py:8:26:8:32 | ControlFlowNode for ImportMember | a 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 750e61d048d..19f96791e87 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,14 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:7:14:7:20 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:30:17:30:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:37:17:37:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:44:17:44:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:60:17:60:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:67:17:67:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:74:17:74:23 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:81:17:81:23 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for test.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 | @@ -16,6 +26,9 @@ edges | 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:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| 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 | @@ -42,11 +55,11 @@ nodes | 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:7:14:7:20 | ControlFlowNode for request | test.py:8:21:8:26 | ControlFlowNode for target | Untrusted URL redirection depends on $@. | test.py:7:14:7:20 | ControlFlowNode for request | a user-provided value | -| test.py:32:21:32:24 | ControlFlowNode for safe | test.py:30:17:30:23 | ControlFlowNode for request | test.py:32:21:32:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:30:17:30:23 | ControlFlowNode for request | a user-provided value | -| test.py:39:21:39:24 | ControlFlowNode for safe | test.py:37:17:37:23 | ControlFlowNode for request | test.py:39:21:39:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:37:17:37:23 | ControlFlowNode for request | a user-provided value | -| test.py:46:21:46:24 | ControlFlowNode for safe | test.py:44:17:44:23 | ControlFlowNode for request | test.py:46:21:46:24 | ControlFlowNode for safe | Untrusted URL redirection depends on $@. | test.py:44:17:44:23 | ControlFlowNode for request | a user-provided value | -| test.py:62:21:62:26 | ControlFlowNode for unsafe | test.py:60:17:60:23 | ControlFlowNode for request | test.py:62:21:62:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:60:17:60:23 | ControlFlowNode for request | a user-provided value | -| test.py:69:21:69:26 | ControlFlowNode for unsafe | test.py:67:17:67:23 | ControlFlowNode for request | test.py:69:21:69:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:67:17:67:23 | ControlFlowNode for request | a user-provided value | -| test.py:76:21:76:26 | ControlFlowNode for unsafe | test.py:74:17:74:23 | ControlFlowNode for request | test.py:76:21:76:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:74:17:74:23 | ControlFlowNode for request | a user-provided value | -| test.py:83:21:83:26 | ControlFlowNode for unsafe | test.py:81:17:81:23 | ControlFlowNode for request | test.py:83:21:83:26 | ControlFlowNode for unsafe | Untrusted URL redirection depends on $@. | test.py:81:17:81:23 | ControlFlowNode for request | a user-provided value | +| 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 $@. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected b/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected index 402ee97db09..3421155d992 100644 --- a/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected +++ b/python/ql/test/query-tests/Security/CWE-611-Xxe/Xxe.expected @@ -1,4 +1,8 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:8:19:8:25 | ControlFlowNode for request | +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:19:19:19:25 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for test.request | | test.py:8:19:8:25 | ControlFlowNode for request | test.py:8:19:8:30 | ControlFlowNode for Attribute | | test.py:8:19:8:30 | ControlFlowNode for Attribute | test.py:8:19:8:45 | ControlFlowNode for Subscript | | test.py:8:19:8:45 | ControlFlowNode for Subscript | test.py:9:34:9:44 | ControlFlowNode for xml_content | @@ -6,6 +10,9 @@ edges | test.py:19:19:19:30 | ControlFlowNode for Attribute | test.py:19:19:19:45 | ControlFlowNode for Subscript | | test.py:19:19:19:45 | ControlFlowNode for Subscript | test.py:30:34:30:44 | ControlFlowNode for xml_content | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| 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:8:19:8:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:8:19:8:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:8:19:8:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -16,5 +23,5 @@ nodes | test.py:30:34:30:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content | subpaths #select -| test.py:9:34:9:44 | ControlFlowNode for xml_content | test.py:8:19:8:25 | ControlFlowNode for request | test.py:9:34:9:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:8:19:8:25 | ControlFlowNode for request | a user-provided value | -| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:19:19:19:25 | ControlFlowNode for request | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:19:19:19:25 | ControlFlowNode for request | a user-provided value | +| test.py:9:34:9:44 | ControlFlowNode for xml_content | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:9:34:9:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against external entity expansion. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a 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 d0068a4b872..a33e851828d 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,6 +2,13 @@ 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:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | +| xpathFlow.py:0:0:0:0 | ModuleVariableNode for xpathFlow.request | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for xpathFlow.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 | @@ -17,6 +24,9 @@ nodes | 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:0:0:0:0 | ModuleVariableNode for xpathFlow.request | semmle.label | ModuleVariableNode for xpathFlow.request | +| 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 | @@ -35,8 +45,8 @@ nodes 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 $@. | xpathBad.py:9:7:9:13 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | a user-provided value | -| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | XPath expression depends on $@. | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | a 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 $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a 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 $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a 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 $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a 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 $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a 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 $@. | xpathFlow.py:2:26:2:32 | ControlFlowNode for ImportMember | a 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 7f5cf5926c0..4646f9c03e9 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,13 +1,19 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:7:12:7:18 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for test.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 | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| 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 | subpaths #select -| test.py:8:30:8:33 | ControlFlowNode for text | test.py:7:12:7:18 | ControlFlowNode for request | test.py:8:30:8:33 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | test.py:8:21:8:23 | \\s+ | regular expression | test.py:7:12:7:18 | ControlFlowNode for request | a user-provided value | -| test.py:9:32:9:35 | ControlFlowNode for text | test.py:7:12:7:18 | ControlFlowNode for request | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on $@ may run slow on strings with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:7:12:7:18 | ControlFlowNode for request | a user-provided value | +| 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 $@ 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 | a 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 $@ may run slow on strings with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected b/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected index 317815142fe..bbc01aab4be 100644 --- a/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-730-RegexInjection/RegexInjection.expected @@ -1,4 +1,9 @@ edges +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | re_bad.py:13:22:13:28 | ControlFlowNode for request | +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | re_bad.py:24:22:24:28 | ControlFlowNode for request | +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | re_bad.py:36:22:36:28 | ControlFlowNode for request | +| re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:1:19:1:25 | GSSA Variable request | +| re_bad.py:1:19:1:25 | GSSA Variable request | re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | | re_bad.py:13:22:13:28 | ControlFlowNode for request | re_bad.py:13:22:13:33 | ControlFlowNode for Attribute | | re_bad.py:13:22:13:33 | ControlFlowNode for Attribute | re_bad.py:13:22:13:44 | ControlFlowNode for Subscript | | re_bad.py:13:22:13:44 | ControlFlowNode for Subscript | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | @@ -9,6 +14,9 @@ edges | re_bad.py:36:22:36:33 | ControlFlowNode for Attribute | re_bad.py:36:22:36:44 | ControlFlowNode for Subscript | | re_bad.py:36:22:36:44 | ControlFlowNode for Subscript | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | nodes +| re_bad.py:0:0:0:0 | ModuleVariableNode for re_bad.request | semmle.label | ModuleVariableNode for re_bad.request | +| re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| re_bad.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | re_bad.py:13:22:13:28 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | re_bad.py:13:22:13:33 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | re_bad.py:13:22:13:44 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | @@ -23,6 +31,6 @@ nodes | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | semmle.label | ControlFlowNode for unsafe_pattern | subpaths #select -| re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | re_bad.py:13:22:13:28 | ControlFlowNode for request | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:13:22:13:28 | ControlFlowNode for request | a user-provided value | re_bad.py:14:5:14:33 | ControlFlowNode for Attribute() | re.search | -| re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | re_bad.py:24:22:24:28 | ControlFlowNode for request | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:24:22:24:28 | ControlFlowNode for request | a user-provided value | re_bad.py:26:5:26:31 | ControlFlowNode for Attribute() | re.search | -| re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | re_bad.py:36:22:36:28 | ControlFlowNode for request | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:36:22:36:28 | ControlFlowNode for request | a user-provided value | re_bad.py:37:5:37:41 | ControlFlowNode for Attribute() | re.search | +| re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:14:15:14:28 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | re_bad.py:14:5:14:33 | ControlFlowNode for Attribute() | re.search | +| re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:25:35:25:48 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | re_bad.py:26:5:26:31 | ControlFlowNode for Attribute() | re.search | +| re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | $@ depends on $@ and executed by $@. | re_bad.py:37:16:37:29 | ControlFlowNode for unsafe_pattern | This regular expression | re_bad.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | re_bad.py:37:5:37:41 | ControlFlowNode for Attribute() | re.search | diff --git a/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected b/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected index 79ebe0bfef7..99f81737974 100644 --- a/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected +++ b/python/ql/test/query-tests/Security/CWE-776-XmlBomb/XmlBomb.expected @@ -1,12 +1,18 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.request | test.py:19:19:19:25 | ControlFlowNode for request | +| 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:0:0:0:0 | ModuleVariableNode for test.request | | test.py:19:19:19:25 | ControlFlowNode for request | test.py:19:19:19:30 | ControlFlowNode for Attribute | | test.py:19:19:19:30 | ControlFlowNode for Attribute | test.py:19:19:19:45 | ControlFlowNode for Subscript | | test.py:19:19:19:45 | ControlFlowNode for Subscript | test.py:30:34:30:44 | ControlFlowNode for xml_content | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.request | semmle.label | ModuleVariableNode for test.request | +| 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:19:19:19:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test.py:19:19:19:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | test.py:19:19:19:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | test.py:30:34:30:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content | subpaths #select -| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:19:19:19:25 | ControlFlowNode for request | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against uncontrolled entity expansion. | test.py:19:19:19:25 | ControlFlowNode for request | a user-provided value | +| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:1:26:1:32 | ControlFlowNode for ImportMember | test.py:30:34:30:44 | ControlFlowNode for xml_content | XML parsing depends on $@ without guarding against uncontrolled entity expansion. | test.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected index cc55c8317e1..9de3a7c1182 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/FullServerSideRequestForgery.expected @@ -1,4 +1,26 @@ edges +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute | @@ -79,6 +101,15 @@ edges | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:11:18:11:24 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | @@ -107,6 +138,12 @@ edges | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:33:25:33:28 | ControlFlowNode for path | | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:37:25:37:28 | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | @@ -114,6 +151,12 @@ edges | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | nodes +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -204,6 +247,12 @@ nodes | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -233,6 +282,12 @@ nodes | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:33:25:33:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | test_http_client.py:37:25:37:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -243,24 +298,22 @@ nodes | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths #select -| full_partial_test.py:10:5:10:28 | ControlFlowNode for Attribute() | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:13:5:13:21 | ControlFlowNode for Attribute() | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:19:5:19:21 | ControlFlowNode for Attribute() | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:23:5:23:21 | ControlFlowNode for Attribute() | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:42:5:42:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:45:5:45:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:48:5:48:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:51:5:51:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:54:5:54:21 | ControlFlowNode for Attribute() | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:62:5:62:21 | ControlFlowNode for Attribute() | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:65:5:65:21 | ControlFlowNode for Attribute() | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:76:5:76:21 | ControlFlowNode for Attribute() | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:79:5:79:21 | ControlFlowNode for Attribute() | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:82:5:82:21 | ControlFlowNode for Attribute() | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value | -| test_requests.py:8:5:8:28 | ControlFlowNode for Attribute() | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | test_requests.py:6:18:6:24 | ControlFlowNode for request | a user-provided value | +| full_partial_test.py:10:5:10:28 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:10:18:10:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:13:5:13:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:13:18:13:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:19:5:19:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:19:18:19:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:23:5:23:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:23:18:23:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:42:5:42:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:42:18:42:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:45:5:45:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:45:18:45:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:48:5:48:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:48:18:48:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:51:5:51:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:51:18:51:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:54:5:54:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:54:18:54:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:62:5:62:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:62:18:62:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:65:5:65:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:65:18:65:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:76:5:76:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:76:18:76:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:79:5:79:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:79:18:79:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:82:5:82:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:82:18:82:20 | ControlFlowNode for url | The full URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:13:27:13:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:14:5:14:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:14:25:14:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:19:5:19:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:19:25:19:35 | ControlFlowNode for unsafe_path | The full URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_requests.py:8:5:8:28 | ControlFlowNode for Attribute() | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | The full URL of this request depends on $@. | test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected index 6206a070a88..7294de47bc2 100644 --- a/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected +++ b/python/ql/test/query-tests/Security/CWE-918-ServerSideRequestForgery/PartialServerSideRequestForgery.expected @@ -1,4 +1,26 @@ edges +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:8:17:8:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:37:18:37:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:38:17:38:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:71:18:71:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:72:17:72:23 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:1:19:1:25 | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | full_partial_test.py:8:17:8:28 | ControlFlowNode for Attribute | @@ -79,6 +101,15 @@ edges | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:9:19:9:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:10:19:10:25 | ControlFlowNode for request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | test_http_client.py:11:18:11:24 | ControlFlowNode for request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:1:26:1:32 | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:10:19:10:30 | ControlFlowNode for Attribute | @@ -107,6 +138,12 @@ edges | test_http_client.py:11:18:11:29 | ControlFlowNode for Attribute | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:33:25:33:28 | ControlFlowNode for path | | test_http_client.py:11:18:11:48 | ControlFlowNode for Subscript | test_http_client.py:37:25:37:28 | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | test_requests.py:6:18:6:24 | ControlFlowNode for request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | test_requests.py:1:19:1:25 | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | GSSA Variable request | test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | | test_requests.py:6:18:6:24 | ControlFlowNode for request | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | @@ -114,6 +151,12 @@ edges | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | | test_requests.py:6:18:6:48 | ControlFlowNode for Subscript | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | nodes +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:0:0:0:0 | ModuleVariableNode for full_partial_test.request | semmle.label | ModuleVariableNode for full_partial_test.request | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| full_partial_test.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:7:18:7:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | full_partial_test.py:7:18:7:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -204,6 +247,12 @@ nodes | full_partial_test.py:119:18:119:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | | full_partial_test.py:119:18:119:48 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | semmle.label | ControlFlowNode for url | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:0:0:0:0 | ModuleVariableNode for test_http_client.request | semmle.label | ModuleVariableNode for test_http_client.request | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_http_client.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:9:19:9:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_http_client.py:9:19:9:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -233,6 +282,12 @@ nodes | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | semmle.label | ControlFlowNode for unsafe_path | | test_http_client.py:33:25:33:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | | test_http_client.py:37:25:37:28 | ControlFlowNode for path | semmle.label | ControlFlowNode for path | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:0:0:0:0 | ModuleVariableNode for test_requests.request | semmle.label | ModuleVariableNode for test_requests.request | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | +| test_requests.py:1:19:1:25 | GSSA Variable request | semmle.label | GSSA Variable request | | test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_requests.py:6:18:6:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | test_requests.py:6:18:6:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | @@ -243,21 +298,15 @@ nodes | test_requests.py:8:18:8:27 | ControlFlowNode for user_input | semmle.label | ControlFlowNode for user_input | subpaths #select -| full_partial_test.py:68:5:68:21 | ControlFlowNode for Attribute() | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:57:18:57:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:68:5:68:21 | ControlFlowNode for Attribute() | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:58:17:58:23 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:89:5:89:21 | ControlFlowNode for Attribute() | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | full_partial_test.py:89:18:89:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:86:18:86:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:95:5:95:21 | ControlFlowNode for Attribute() | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | full_partial_test.py:95:18:95:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:92:18:92:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:101:5:101:21 | ControlFlowNode for Attribute() | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | full_partial_test.py:101:18:101:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:98:18:98:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:107:5:107:21 | ControlFlowNode for Attribute() | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | full_partial_test.py:107:18:107:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:104:18:104:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:116:5:116:21 | ControlFlowNode for Attribute() | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | full_partial_test.py:116:18:116:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:110:18:110:24 | ControlFlowNode for request | a user-provided value | -| full_partial_test.py:122:5:122:21 | ControlFlowNode for Attribute() | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:119:18:119:24 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:22:5:22:31 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:26:5:26:31 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:29:5:29:36 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | Part of the URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:29:5:29:36 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | Part of the URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:33:25:33:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:33:25:33:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:33:25:33:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:11:18:11:24 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:9:19:9:25 | ControlFlowNode for request | test_http_client.py:37:25:37:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:9:19:9:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:10:19:10:25 | ControlFlowNode for request | test_http_client.py:37:25:37:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:10:19:10:25 | ControlFlowNode for request | a user-provided value | -| test_http_client.py:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:11:18:11:24 | ControlFlowNode for request | test_http_client.py:37:25:37:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:11:18:11:24 | ControlFlowNode for request | a user-provided value | +| full_partial_test.py:68:5:68:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:68:18:68:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:89:5:89:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:89:18:89:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:95:5:95:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:95:18:95:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:101:5:101:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:101:18:101:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:107:5:107:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:107:18:107:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:116:5:116:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:116:18:116:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| full_partial_test.py:122:5:122:21 | ControlFlowNode for Attribute() | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | full_partial_test.py:122:18:122:20 | ControlFlowNode for url | Part of the URL of this request depends on $@. | full_partial_test.py:1:19:1:25 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:22:5:22:31 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:18:27:18:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:26:5:26:31 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:25:27:25:37 | ControlFlowNode for unsafe_host | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:29:5:29:36 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:29:25:29:35 | ControlFlowNode for unsafe_path | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:33:5:33:29 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:33:25:33:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | +| test_http_client.py:37:5:37:29 | ControlFlowNode for Attribute() | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | test_http_client.py:37:25:37:28 | ControlFlowNode for path | Part of the URL of this request depends on $@. | test_http_client.py:1:26:1:32 | ControlFlowNode for ImportMember | a user-provided value | diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 1a96d857e7f..677403b9a16 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,26 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The following classes have been moved from `codeql.ruby.frameworks.ActionController` to `codeql.ruby.frameworks.Rails`: + * `ParamsCall`, now accessed as `Rails::ParamsCall`. + * `CookieCall`, now accessed as `Rails::CookieCall`. +* The following classes have been moved from `codeql.ruby.frameworks.ActionView` to `codeql.ruby.frameworks.Rails`: + * `HtmlSafeCall`, now accessed as `Rails::HtmlSafeCall`. + * `HtmlEscapeCall`, now accessed as `Rails::HtmlEscapeCall`. + * `RenderCall`, now accessed as `Rails::RenderCall`. + * `RenderToCall`, now accessed as `Rails::RenderToCall`. +* Subclasses of `ActionController::Metal` are now recognised as controllers. +* `ActionController::DataStreaming::send_file` is now recognized as a + `FileSystemAccess`. +* Various XSS sinks in the ActionView library are now recognized. +* Calls to `ActiveRecord::Base.create` are now recognized as model + instantiations. +* Various code executions, command executions and HTTP requests in the + ActiveStorage library are now recognized. +* `MethodBase` now has two new predicates related to visibility: `isPublic` and + `isProtected`. These hold, respectively, if the method is public or protected. + ## 0.4.0 ### Breaking Changes diff --git a/ruby/ql/lib/change-notes/2022-08-16-protected-methods.md b/ruby/ql/lib/change-notes/2022-08-16-protected-methods.md deleted file mode 100644 index 7647517c06c..00000000000 --- a/ruby/ql/lib/change-notes/2022-08-16-protected-methods.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* `MethodBase` now has two new predicates related to visibility: `isPublic` and - `isProtected`. These hold, respectively, if the method is public or protected. diff --git a/ruby/ql/lib/change-notes/2022-08-30-activestorage.md b/ruby/ql/lib/change-notes/2022-08-30-activestorage.md deleted file mode 100644 index b5ab9e34479..00000000000 --- a/ruby/ql/lib/change-notes/2022-08-30-activestorage.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* Various code executions, command executions and HTTP requests in the - ActiveStorage library are now recognized. - diff --git a/ruby/ql/lib/change-notes/2022-09-27-actionview.md b/ruby/ql/lib/change-notes/2022-09-27-actionview.md deleted file mode 100644 index d8f392971ad..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-27-actionview.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Various XSS sinks in the ActionView library are now recognized. diff --git a/ruby/ql/lib/change-notes/2022-09-27-activerecord-create.md b/ruby/ql/lib/change-notes/2022-09-27-activerecord-create.md deleted file mode 100644 index b16da83f611..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-27-activerecord-create.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* Calls to `ActiveRecord::Base.create` are now recognized as model - instantiations. diff --git a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-metal.md b/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-metal.md deleted file mode 100644 index 4d4e2fef174..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-metal.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Subclasses of `ActionController::Metal` are now recognised as controllers. diff --git a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-sendfile.md b/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-sendfile.md deleted file mode 100644 index 93bf546f4a5..00000000000 --- a/ruby/ql/lib/change-notes/2022-09-28-actioncontroller-sendfile.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -category: minorAnalysis ---- -* `ActionController::DataStreaming::send_file` is now recognized as a - `FileSystemAccess`. - diff --git a/ruby/ql/lib/change-notes/2022-10-04-actionview-controller-renames.md b/ruby/ql/lib/change-notes/2022-10-04-actionview-controller-renames.md deleted file mode 100644 index f269442dcf4..00000000000 --- a/ruby/ql/lib/change-notes/2022-10-04-actionview-controller-renames.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -category: minorAnalysis ---- -* The following classes have been moved from `codeql.ruby.frameworks.ActionController` to `codeql.ruby.frameworks.Rails`: - * `ParamsCall`, now accessed as `Rails::ParamsCall`. - * `CookieCall`, now accessed as `Rails::CookieCall`. -* The following classes have been moved from `codeql.ruby.frameworks.ActionView` to `codeql.ruby.frameworks.Rails`: - * `HtmlSafeCall`, now accessed as `Rails::HtmlSafeCall`. - * `HtmlEscapeCall`, now accessed as `Rails::HtmlEscapeCall`. - * `RenderCall`, now accessed as `Rails::RenderCall`. - * `RenderToCall`, now accessed as `Rails::RenderToCall`. diff --git a/ruby/ql/lib/change-notes/released/0.4.1.md b/ruby/ql/lib/change-notes/released/0.4.1.md new file mode 100644 index 00000000000..9c492f4ac7e --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.4.1.md @@ -0,0 +1,22 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The following classes have been moved from `codeql.ruby.frameworks.ActionController` to `codeql.ruby.frameworks.Rails`: + * `ParamsCall`, now accessed as `Rails::ParamsCall`. + * `CookieCall`, now accessed as `Rails::CookieCall`. +* The following classes have been moved from `codeql.ruby.frameworks.ActionView` to `codeql.ruby.frameworks.Rails`: + * `HtmlSafeCall`, now accessed as `Rails::HtmlSafeCall`. + * `HtmlEscapeCall`, now accessed as `Rails::HtmlEscapeCall`. + * `RenderCall`, now accessed as `Rails::RenderCall`. + * `RenderToCall`, now accessed as `Rails::RenderToCall`. +* Subclasses of `ActionController::Metal` are now recognised as controllers. +* `ActionController::DataStreaming::send_file` is now recognized as a + `FileSystemAccess`. +* Various XSS sinks in the ActionView library are now recognized. +* Calls to `ActiveRecord::Base.create` are now recognized as model + instantiations. +* Various code executions, command executions and HTTP requests in the + ActiveStorage library are now recognized. +* `MethodBase` now has two new predicates related to visibility: `isPublic` and + `isProtected`. These hold, respectively, if the method is public or protected. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll index 9a9626cf74f..67b53baa51c 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll @@ -486,12 +486,15 @@ private import ResolveImpl * methods evaluate the block in the context of some other module/class instead of * the enclosing one. */ -private ModuleBase enclosingModule(AstNode node) { result = parent*(node).getParent() } - -private AstNode parent(AstNode n) { - result = n.getParent() and - not result instanceof ModuleBase and - not result instanceof Block +private ModuleBase enclosingModule(AstNode node) { + result = node.getParent() + or + exists(AstNode mid | + result = enclosingModule(mid) and + mid = node.getParent() and + not mid instanceof ModuleBase and + not mid instanceof Block + ) } private Module getAncestors(Module m) { diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index 6eaafee71af..1ab4435a85a 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -118,7 +118,11 @@ class Synthesis extends TSynthesis { private class Desugared extends AstNode { Desugared() { this = any(AstNode sugar).getDesugared() } - AstNode getADescendant() { result = this.getAChild*() } + AstNode getADescendant() { + result = this + or + result = this.getADescendant().getAChild() + } } /** @@ -132,7 +136,10 @@ int desugarLevel(AstNode n) { result = count(Desugared desugared | n = desugared * Holds if `n` appears in a context that is desugared. That is, a * transitive, reflexive parent of `n` is a desugared node. */ -predicate isInDesugaredContext(AstNode n) { n = any(AstNode sugar).getDesugared().getAChild*() } +predicate isInDesugaredContext(AstNode n) { + n = any(AstNode sugar).getDesugared() or + n = any(AstNode mid | isInDesugaredContext(mid)).getAChild() +} /** * Holds if `n` is a node that only exists as a result of desugaring some diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll index 7615357453d..fe4cca24d69 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll @@ -71,18 +71,22 @@ private predicate completionIsValidForStmt(AstNode n, Completion c) { c = TReturnCompletion() } +private AstNode getARescuableBodyChild() { + exists(Trees::BodyStmtTree bst | result = bst.getBodyChild(_, true) | + exists(bst.getARescue()) + or + exists(bst.getEnsure()) + ) + or + result = getARescuableBodyChild().getAChild() +} + /** * Holds if `c` happens in an exception-aware context, that is, it may be * `rescue`d or `ensure`d. In such cases, we assume that the target of `c` * may raise an exception (in addition to evaluating normally). */ -private predicate mayRaise(Call c) { - exists(Trees::BodyStmtTree bst | c = bst.getBodyChild(_, true).getAChild*() | - exists(bst.getARescue()) - or - exists(bst.getEnsure()) - ) -} +private predicate mayRaise(Call c) { c = getARescuableBodyChild() } /** A completion of a statement or an expression. */ abstract class Completion extends TCompletion { diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll index b7e9b14a910..f988ea43779 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll @@ -389,7 +389,7 @@ private module Cached { // ``` exists(DataFlow::Node sourceNode, Module m | flowsToMethodCall(call, sourceNode, method) and - singletonMethodOnModule(result, method, m) + result = lookupSingletonMethod(m, method) | // ```rb // def C.singleton; end # <- result @@ -725,7 +725,10 @@ private predicate singletonMethodOnModule(MethodBase method, string name, Module selfInModule(object.(SelfVariableReadAccess).getVariable(), m) ) or - flowsToSingletonMethodObject(trackModuleAccess(m), method, name) + exists(DataFlow::LocalSourceNode sourceNode | + m = resolveConstantReadAccess(sourceNode.asExpr().getExpr()) and + flowsToSingletonMethodObject(sourceNode, method, name) + ) or exists(Module other | extendCallModule(m, other) and @@ -733,6 +736,26 @@ private predicate singletonMethodOnModule(MethodBase method, string name, Module ) } +/** + * Holds if `method` is a singleton method named `name`, defined on module + * `m`, or any transitive base class of `m`. + */ +pragma[nomagic] +private MethodBase lookupSingletonMethod(Module m, string name) { + singletonMethodOnModule(result, name, m) + or + // cannot be part of `singletonMethodOnModule` because it would introduce + // negative recursion below + exists(DataFlow::LocalSourceNode sourceNode | + sourceNode = trackModuleAccess(m) and + not m = resolveConstantReadAccess(sourceNode.asExpr().getExpr()) and + flowsToSingletonMethodObject(sourceNode, result, name) + ) + or + not singletonMethodOnModule(_, name, m) and + result = lookupSingletonMethod(m.getSuperClass(), name) +} + /** * Holds if `method` is a singleton method named `name`, defined on expression * `object`, where `object` is not likely to resolve to a module: diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForRegExp.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll index 4468f8ffa58..37b3cdbd576 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll @@ -70,6 +70,7 @@ class ExconHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll index ae4bb25c265..139a484f87a 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll @@ -71,6 +71,7 @@ class FaradayHttpRequest extends Http::Client::Request::Range, DataFlow::CallNod ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll index 0d8e6cfa0fc..51537e25148 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll @@ -61,6 +61,7 @@ class HttpClientRequest extends Http::Client::Request::Range, DataFlow::CallNode .getArgument(0) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll index 08ab0f94141..e0b5de43351 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll @@ -53,6 +53,7 @@ class HttpartyRequest extends Http::Client::Request::Range, DataFlow::CallNode { result = this.getKeywordArgumentIncludeHashArgument(["verify", "verify_peer"]) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll index f12f6fa8e30..d6dbd581f86 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll @@ -80,6 +80,7 @@ class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll index f11a4b2908f..68ca62beaf8 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll @@ -42,6 +42,7 @@ class OpenUriRequest extends Http::Client::Request::Range, DataFlow::CallNode { result = this.getKeywordArgumentIncludeHashArgument("ssl_verify_mode") } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { @@ -91,6 +92,7 @@ class OpenUriKernelOpenRequest extends Http::Client::Request::Range, DataFlow::C ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll index 4b9ddfaab41..7df9875b00c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll @@ -54,6 +54,7 @@ class RestClientHttpRequest extends Http::Client::Request::Range, DataFlow::Call ) } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll index 163560e61f9..e41add437d3 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll @@ -34,6 +34,7 @@ class TyphoeusHttpRequest extends Http::Client::Request::Range, DataFlow::CallNo result = this.getKeywordArgumentIncludeHashArgument("ssl_verifypeer") } + cached override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll index 0939e6c17c8..85db78252c8 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll @@ -27,6 +27,7 @@ module Pathname { * Every `PathnameInstance` is considered to be a `FileNameSource`. */ class PathnameInstance extends FileNameSource { + cached PathnameInstance() { any(PathnameConfiguration c).hasFlowTo(this) } } diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 97c480b8f6e..1ed112d89d4 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.4.1-dev +version: 0.4.2-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index e45d4e8c250..6792b3e61c0 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.4.1 + +### Minor Analysis Improvements + +* The `rb/xxe` query has been updated to add the following sinks for XML external entity expansion: + 1. Calls to parse XML using `LibXML` when its `default_substitute_entities` option is enabled. + 2. Uses of the Rails methods `ActiveSupport::XmlMini.parse`, `Hash.from_xml`, and `Hash.from_trusted_xml` when `ActiveSupport::XmlMini` is configured to use `LibXML` as its backend, and its `default_substitute_entities` option is enabled. + ## 0.4.0 ### New Queries diff --git a/ruby/ql/src/change-notes/2022-09-27-libxml-xxe.md b/ruby/ql/src/change-notes/released/0.4.1.md similarity index 80% rename from ruby/ql/src/change-notes/2022-09-27-libxml-xxe.md rename to ruby/ql/src/change-notes/released/0.4.1.md index a3084c62f2a..a3ee4612257 100644 --- a/ruby/ql/src/change-notes/2022-09-27-libxml-xxe.md +++ b/ruby/ql/src/change-notes/released/0.4.1.md @@ -1,6 +1,7 @@ ---- -category: minorAnalysis ---- +## 0.4.1 + +### Minor Analysis Improvements + * The `rb/xxe` query has been updated to add the following sinks for XML external entity expansion: 1. Calls to parse XML using `LibXML` when its `default_substitute_entities` option is enabled. - 2. Uses of the Rails methods `ActiveSupport::XmlMini.parse`, `Hash.from_xml`, and `Hash.from_trusted_xml` when `ActiveSupport::XmlMini` is configured to use `LibXML` as its backend, and its `default_substitute_entities` option is enabled. \ No newline at end of file + 2. Uses of the Rails methods `ActiveSupport::XmlMini.parse`, `Hash.from_xml`, and `Hash.from_trusted_xml` when `ActiveSupport::XmlMini` is configured to use `LibXML` as its backend, and its `default_substitute_entities` option is enabled. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 458bfbeccff..89fa3a87180 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.0 +lastReleaseVersion: 0.4.1 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 66f006ac2d5..43e9df97f13 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.4.1-dev +version: 0.4.2-dev groups: - ruby - queries diff --git a/ruby/ql/src/queries/meta/TaintedNodes.ql b/ruby/ql/src/queries/meta/TaintedNodes.ql new file mode 100644 index 00000000000..18997cfaaee --- /dev/null +++ b/ruby/ql/src/queries/meta/TaintedNodes.ql @@ -0,0 +1,28 @@ +/** + * @name Tainted nodes + * @description Nodes reachable from a remote flow source via default taint-tracking steps. + * @kind problem + * @problem.severity recommendation + * @id rb/meta/tainted-nodes + * @tags meta + * @precision very-low + */ + +import internal.TaintMetrics +import codeql.ruby.DataFlow +import codeql.ruby.TaintTracking + +class BasicTaintConfiguration extends TaintTracking::Configuration { + BasicTaintConfiguration() { this = "BasicTaintConfiguration" } + + override predicate isSource(DataFlow::Node node) { node = relevantTaintSource(_) } + + override predicate isSink(DataFlow::Node node) { + // To reduce noise from synthetic nodes, only count nodes that have an associated expression. + exists(node.asExpr().getExpr()) + } +} + +from DataFlow::Node node +where any(BasicTaintConfiguration cfg).hasFlow(_, node) +select node, "Tainted node" diff --git a/ruby/ql/src/queries/meta/internal/TaintMetrics.qll b/ruby/ql/src/queries/meta/internal/TaintMetrics.qll index 19e25f3a94b..19d26103cb9 100644 --- a/ruby/ql/src/queries/meta/internal/TaintMetrics.qll +++ b/ruby/ql/src/queries/meta/internal/TaintMetrics.qll @@ -36,3 +36,10 @@ DataFlow::Node relevantTaintSink(string kind) { kind = "UrlRedirect" and result instanceof UrlRedirect::Sink ) } + +/** + * Gets the root folder of the snapshot. + * + * This is selected as the location for project-wide metrics. + */ +Folder projectRoot() { result.getRelativePath() = "" } 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 3121b1e71ef..412ba5534b8 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 @@ -5,10 +5,12 @@ import ruby import TestUtilities.InlineFlowTest import PathGraph -import codeql.ruby.frameworks.ActionController +import codeql.ruby.frameworks.Rails class ParamsTaintFlowConf extends DefaultTaintFlowConf { - override predicate isSource(DataFlow::Node n) { n.asExpr().getExpr() instanceof ParamsCall } + override predicate isSource(DataFlow::Node n) { + n.asExpr().getExpr() instanceof Rails::ParamsCall + } } from DataFlow::PathNode source, DataFlow::PathNode sink, ParamsTaintFlowConf conf diff --git a/ruby/ql/test/library-tests/modules/ancestors.expected b/ruby/ql/test/library-tests/modules/ancestors.expected index 2de1b03148e..98cfa6c7186 100644 --- a/ruby/ql/test/library-tests/modules/ancestors.expected +++ b/ruby/ql/test/library-tests/modules/ancestors.expected @@ -89,25 +89,25 @@ calls.rb: # 377| SingletonOverride1 #-----| super -> Object -# 402| SingletonOverride2 +# 404| SingletonOverride2 #-----| super -> SingletonOverride1 -# 417| ConditionalInstanceMethods +# 421| ConditionalInstanceMethods #-----| super -> Object -# 480| ExtendSingletonMethod +# 484| ExtendSingletonMethod -# 490| ExtendSingletonMethod2 +# 494| ExtendSingletonMethod2 -# 496| ExtendSingletonMethod3 +# 500| ExtendSingletonMethod3 -# 509| ProtectedMethodInModule +# 513| ProtectedMethodInModule -# 515| ProtectedMethods +# 519| ProtectedMethods #-----| super -> Object #-----| include -> ProtectedMethodInModule -# 534| ProtectedMethodsSub +# 538| ProtectedMethodsSub #-----| super -> ProtectedMethods hello.rb: diff --git a/ruby/ql/test/library-tests/modules/callgraph.expected b/ruby/ql/test/library-tests/modules/callgraph.expected index 25147f93b1b..df2bffe2933 100644 --- a/ruby/ql/test/library-tests/modules/callgraph.expected +++ b/ruby/ql/test/library-tests/modules/callgraph.expected @@ -148,67 +148,73 @@ getTarget | calls.rb:375:1:375:11 | call to instance | calls.rb:368:5:370:7 | instance | | calls.rb:380:13:380:48 | call to puts | calls.rb:102:5:102:30 | puts | | calls.rb:384:13:384:22 | call to singleton1 | calls.rb:379:9:381:11 | singleton1 | -| calls.rb:384:13:384:22 | call to singleton1 | calls.rb:404:9:406:11 | singleton1 | +| calls.rb:384:13:384:22 | call to singleton1 | calls.rb:406:9:408:11 | singleton1 | | calls.rb:389:9:389:44 | call to puts | calls.rb:102:5:102:30 | puts | | calls.rb:393:9:393:18 | call to singleton2 | calls.rb:388:5:390:7 | singleton2 | -| calls.rb:393:9:393:18 | call to singleton2 | calls.rb:409:5:411:7 | singleton2 | +| calls.rb:393:9:393:18 | call to singleton2 | calls.rb:411:5:413:7 | singleton2 | | calls.rb:396:5:396:14 | call to singleton2 | calls.rb:388:5:390:7 | singleton2 | -| calls.rb:399:1:399:34 | call to call_singleton1 | calls.rb:383:9:385:11 | call_singleton1 | -| calls.rb:400:1:400:34 | call to call_singleton2 | calls.rb:392:5:394:7 | call_singleton2 | -| calls.rb:405:13:405:48 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:410:9:410:44 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:420:13:420:48 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:425:9:425:44 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:428:13:428:48 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:431:17:431:52 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:439:9:443:11 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:439:9:443:15 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:441:17:441:40 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:447:1:447:30 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:447:1:447:33 | call to m1 | calls.rb:419:9:421:11 | m1 | -| calls.rb:448:1:448:30 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:449:1:449:30 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:449:1:449:33 | call to m2 | calls.rb:424:5:436:7 | m2 | -| calls.rb:450:1:450:30 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:399:1:399:29 | call to singleton1 | calls.rb:379:9:381:11 | singleton1 | +| calls.rb:400:1:400:29 | call to singleton2 | calls.rb:388:5:390:7 | singleton2 | +| calls.rb:401:1:401:34 | call to call_singleton1 | calls.rb:383:9:385:11 | call_singleton1 | +| calls.rb:402:1:402:34 | call to call_singleton2 | calls.rb:392:5:394:7 | call_singleton2 | +| calls.rb:407:13:407:48 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:412:9:412:44 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:416:1:416:29 | call to singleton1 | calls.rb:406:9:408:11 | singleton1 | +| calls.rb:417:1:417:29 | call to singleton2 | calls.rb:411:5:413:7 | singleton2 | +| calls.rb:418:1:418:34 | call to call_singleton1 | calls.rb:383:9:385:11 | call_singleton1 | +| calls.rb:419:1:419:34 | call to call_singleton2 | calls.rb:392:5:394:7 | call_singleton2 | +| calls.rb:424:13:424:48 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:429:9:429:44 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:432:13:432:48 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:435:17:435:52 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:443:9:447:11 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:443:9:447:15 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:445:17:445:40 | call to puts | calls.rb:102:5:102:30 | puts | | calls.rb:451:1:451:30 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:451:1:451:33 | call to m1 | calls.rb:423:9:425:11 | m1 | | calls.rb:452:1:452:30 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:454:27:472:3 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:457:13:457:22 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:461:5:465:7 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:461:5:465:11 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:463:13:463:22 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:469:13:469:27 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:474:1:474:27 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:475:1:475:27 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:476:1:476:27 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:477:1:477:27 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:453:1:453:30 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:453:1:453:33 | call to m2 | calls.rb:428:5:440:7 | m2 | +| calls.rb:454:1:454:30 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:455:1:455:30 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:456:1:456:30 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:458:27:476:3 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:461:13:461:22 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:465:5:469:7 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:465:5:469:11 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:467:13:467:22 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:473:13:473:27 | call to puts | calls.rb:102:5:102:30 | puts | | calls.rb:478:1:478:27 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:488:1:488:31 | call to singleton | calls.rb:481:5:483:7 | singleton | -| calls.rb:494:1:494:32 | call to singleton | calls.rb:481:5:483:7 | singleton | -| calls.rb:501:1:501:32 | call to singleton | calls.rb:481:5:483:7 | singleton | -| calls.rb:507:1:507:13 | call to singleton | calls.rb:481:5:483:7 | singleton | -| calls.rb:516:5:516:35 | call to include | calls.rb:108:5:110:7 | include | -| calls.rb:519:9:519:35 | call to puts | calls.rb:102:5:102:30 | puts | -| calls.rb:523:9:523:11 | call to foo | calls.rb:510:15:512:7 | foo | -| calls.rb:524:9:524:11 | call to bar | calls.rb:518:15:520:7 | bar | -| calls.rb:525:9:525:28 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:525:9:525:32 | call to foo | calls.rb:510:15:512:7 | foo | -| calls.rb:526:9:526:28 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:526:9:526:32 | call to bar | calls.rb:518:15:520:7 | bar | -| calls.rb:530:1:530:20 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:531:1:531:20 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:532:1:532:20 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:532:1:532:24 | call to baz | calls.rb:522:5:527:7 | baz | -| calls.rb:536:9:536:11 | call to foo | calls.rb:510:15:512:7 | foo | -| calls.rb:537:9:537:31 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:537:9:537:35 | call to foo | calls.rb:510:15:512:7 | foo | -| calls.rb:541:1:541:23 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:542:1:542:23 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:543:1:543:23 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:543:1:543:27 | call to baz | calls.rb:535:5:538:7 | baz | -| calls.rb:545:2:545:6 | call to new | calls.rb:117:5:117:16 | new | -| calls.rb:545:20:545:24 | call to baz | calls.rb:51:5:57:7 | baz | -| calls.rb:546:26:546:37 | call to capitalize | calls.rb:97:5:97:23 | capitalize | +| calls.rb:479:1:479:27 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:480:1:480:27 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:481:1:481:27 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:482:1:482:27 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:492:1:492:31 | call to singleton | calls.rb:485:5:487:7 | singleton | +| calls.rb:498:1:498:32 | call to singleton | calls.rb:485:5:487:7 | singleton | +| calls.rb:505:1:505:32 | call to singleton | calls.rb:485:5:487:7 | singleton | +| calls.rb:511:1:511:13 | call to singleton | calls.rb:485:5:487:7 | singleton | +| calls.rb:520:5:520:35 | call to include | calls.rb:108:5:110:7 | include | +| calls.rb:523:9:523:35 | call to puts | calls.rb:102:5:102:30 | puts | +| calls.rb:527:9:527:11 | call to foo | calls.rb:514:15:516:7 | foo | +| calls.rb:528:9:528:11 | call to bar | calls.rb:522:15:524:7 | bar | +| calls.rb:529:9:529:28 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:529:9:529:32 | call to foo | calls.rb:514:15:516:7 | foo | +| calls.rb:530:9:530:28 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:530:9:530:32 | call to bar | calls.rb:522:15:524:7 | bar | +| calls.rb:534:1:534:20 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:535:1:535:20 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:536:1:536:20 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:536:1:536:24 | call to baz | calls.rb:526:5:531:7 | baz | +| calls.rb:540:9:540:11 | call to foo | calls.rb:514:15:516:7 | foo | +| calls.rb:541:9:541:31 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:541:9:541:35 | call to foo | calls.rb:514:15:516:7 | foo | +| calls.rb:545:1:545:23 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:546:1:546:23 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:547:1:547:23 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:547:1:547:27 | call to baz | calls.rb:539:5:542:7 | baz | +| calls.rb:549:2:549:6 | call to new | calls.rb:117:5:117:16 | new | +| calls.rb:549:20:549:24 | call to baz | calls.rb:51:5:57:7 | baz | +| calls.rb:550:26:550:37 | call to capitalize | calls.rb:97:5:97:23 | capitalize | | hello.rb:12:5:12:24 | call to include | calls.rb:108:5:110:7 | include | | hello.rb:14:16:14:20 | call to hello | hello.rb:2:5:4:7 | hello | | hello.rb:20:16:20:20 | call to super | hello.rb:13:5:15:7 | message | @@ -286,46 +292,44 @@ unresolvedCall | calls.rb:274:1:274:14 | call to singleton_g | | calls.rb:276:1:276:14 | call to singleton_g | | calls.rb:313:9:313:20 | call to instance | -| calls.rb:414:1:414:34 | call to call_singleton1 | -| calls.rb:415:1:415:34 | call to call_singleton2 | -| calls.rb:418:8:418:13 | call to rand | -| calls.rb:418:8:418:17 | ... > ... | -| calls.rb:435:9:435:10 | call to m3 | -| calls.rb:438:8:438:13 | call to rand | -| calls.rb:438:8:438:17 | ... > ... | -| calls.rb:439:9:443:18 | call to m5 | -| calls.rb:448:1:448:33 | call to m3 | -| calls.rb:450:1:450:33 | call to m3 | -| calls.rb:451:1:451:33 | call to m4 | -| calls.rb:452:1:452:33 | call to m5 | -| calls.rb:455:5:455:11 | call to [] | -| calls.rb:455:5:459:7 | call to each | -| calls.rb:461:5:465:15 | call to bar | -| calls.rb:467:5:467:11 | call to [] | -| calls.rb:467:5:471:7 | call to each | -| calls.rb:468:9:470:11 | call to define_method | -| calls.rb:474:1:474:31 | call to foo | -| calls.rb:475:1:475:31 | call to bar | -| calls.rb:476:1:476:33 | call to baz_0 | -| calls.rb:477:1:477:33 | call to baz_1 | -| calls.rb:478:1:478:33 | call to baz_2 | -| calls.rb:482:9:482:46 | call to puts | -| calls.rb:485:5:485:15 | call to extend | -| calls.rb:491:5:491:32 | call to extend | -| calls.rb:499:1:499:51 | call to extend | -| calls.rb:504:1:504:13 | call to singleton | -| calls.rb:505:1:505:32 | call to extend | -| calls.rb:510:5:512:7 | call to protected | -| calls.rb:511:9:511:42 | call to puts | -| calls.rb:518:5:520:7 | call to protected | -| calls.rb:530:1:530:24 | call to foo | -| calls.rb:531:1:531:24 | call to bar | -| calls.rb:541:1:541:27 | call to foo | -| calls.rb:542:1:542:27 | call to bar | -| calls.rb:545:1:545:7 | call to [] | -| calls.rb:545:1:545:26 | call to each | -| calls.rb:546:1:546:13 | call to [] | -| calls.rb:546:1:546:39 | call to each | +| calls.rb:422:8:422:13 | call to rand | +| calls.rb:422:8:422:17 | ... > ... | +| calls.rb:439:9:439:10 | call to m3 | +| calls.rb:442:8:442:13 | call to rand | +| calls.rb:442:8:442:17 | ... > ... | +| calls.rb:443:9:447:18 | call to m5 | +| calls.rb:452:1:452:33 | call to m3 | +| calls.rb:454:1:454:33 | call to m3 | +| calls.rb:455:1:455:33 | call to m4 | +| calls.rb:456:1:456:33 | call to m5 | +| calls.rb:459:5:459:11 | call to [] | +| calls.rb:459:5:463:7 | call to each | +| calls.rb:465:5:469:15 | call to bar | +| calls.rb:471:5:471:11 | call to [] | +| calls.rb:471:5:475:7 | call to each | +| calls.rb:472:9:474:11 | call to define_method | +| calls.rb:478:1:478:31 | call to foo | +| calls.rb:479:1:479:31 | call to bar | +| calls.rb:480:1:480:33 | call to baz_0 | +| calls.rb:481:1:481:33 | call to baz_1 | +| calls.rb:482:1:482:33 | call to baz_2 | +| calls.rb:486:9:486:46 | call to puts | +| calls.rb:489:5:489:15 | call to extend | +| calls.rb:495:5:495:32 | call to extend | +| calls.rb:503:1:503:51 | call to extend | +| calls.rb:508:1:508:13 | call to singleton | +| calls.rb:509:1:509:32 | call to extend | +| calls.rb:514:5:516:7 | call to protected | +| calls.rb:515:9:515:42 | call to puts | +| calls.rb:522:5:524:7 | call to protected | +| calls.rb:534:1:534:24 | call to foo | +| calls.rb:535:1:535:24 | call to bar | +| calls.rb:545:1:545:27 | call to foo | +| calls.rb:546:1:546:27 | call to bar | +| calls.rb:549:1:549:7 | call to [] | +| calls.rb:549:1:549:26 | call to each | +| calls.rb:550:1:550:13 | call to [] | +| calls.rb:550:1:550:39 | call to each | | hello.rb:20:16:20:26 | ... + ... | | hello.rb:20:16:20:34 | ... + ... | | hello.rb:20:16:20:40 | ... + ... | @@ -351,8 +355,8 @@ privateMethod | calls.rb:278:1:286:3 | create | | calls.rb:343:1:359:3 | pattern_dispatch | | calls.rb:367:1:371:3 | add_singleton | -| calls.rb:456:9:458:11 | foo | -| calls.rb:462:9:464:11 | bar | +| calls.rb:460:9:462:11 | foo | +| calls.rb:466:9:468:11 | bar | | private.rb:2:11:3:5 | private1 | | private.rb:8:3:9:5 | private2 | | private.rb:14:3:15:5 | private3 | @@ -417,16 +421,16 @@ publicMethod | calls.rb:383:9:385:11 | call_singleton1 | | calls.rb:388:5:390:7 | singleton2 | | calls.rb:392:5:394:7 | call_singleton2 | -| calls.rb:404:9:406:11 | singleton1 | -| calls.rb:409:5:411:7 | singleton2 | -| calls.rb:419:9:421:11 | m1 | -| calls.rb:424:5:436:7 | m2 | -| calls.rb:427:9:433:11 | m3 | -| calls.rb:430:13:432:15 | m4 | -| calls.rb:440:13:442:15 | m5 | -| calls.rb:481:5:483:7 | singleton | -| calls.rb:522:5:527:7 | baz | -| calls.rb:535:5:538:7 | baz | +| calls.rb:406:9:408:11 | singleton1 | +| calls.rb:411:5:413:7 | singleton2 | +| calls.rb:423:9:425:11 | m1 | +| calls.rb:428:5:440:7 | m2 | +| calls.rb:431:9:437:11 | m3 | +| calls.rb:434:13:436:15 | m4 | +| calls.rb:444:13:446:15 | m5 | +| calls.rb:485:5:487:7 | singleton | +| calls.rb:526:5:531:7 | baz | +| calls.rb:539:5:542:7 | baz | | hello.rb:2:5:4:7 | hello | | hello.rb:5:5:7:7 | world | | hello.rb:13:5:15:7 | message | @@ -443,7 +447,7 @@ publicMethod | private.rb:66:3:67:5 | public | | private.rb:91:3:93:5 | call_m1 | protectedMethod -| calls.rb:510:15:512:7 | foo | -| calls.rb:518:15:520:7 | bar | +| calls.rb:514:15:516:7 | foo | +| calls.rb:522:15:524:7 | bar | | private.rb:32:3:33:5 | protected1 | | private.rb:35:3:36:5 | protected2 | diff --git a/ruby/ql/test/library-tests/modules/calls.rb b/ruby/ql/test/library-tests/modules/calls.rb index 4f5ab8bf966..4996ed93bb3 100644 --- a/ruby/ql/test/library-tests/modules/calls.rb +++ b/ruby/ql/test/library-tests/modules/calls.rb @@ -396,6 +396,8 @@ class SingletonOverride1 singleton2 end +SingletonOverride1.singleton1 +SingletonOverride1.singleton2 SingletonOverride1.call_singleton1 SingletonOverride1.call_singleton2 @@ -411,6 +413,8 @@ class SingletonOverride2 < SingletonOverride1 end end +SingletonOverride2.singleton1 +SingletonOverride2.singleton2 SingletonOverride2.call_singleton1 SingletonOverride2.call_singleton2 diff --git a/ruby/ql/test/library-tests/modules/methods.expected b/ruby/ql/test/library-tests/modules/methods.expected index b9ade37cf67..d7d30b4f2e7 100644 --- a/ruby/ql/test/library-tests/modules/methods.expected +++ b/ruby/ql/test/library-tests/modules/methods.expected @@ -36,13 +36,13 @@ getMethod | calls.rb:325:1:329:3 | C1 | instance | calls.rb:326:5:328:7 | instance | | calls.rb:331:1:335:3 | C2 | instance | calls.rb:332:5:334:7 | instance | | calls.rb:337:1:341:3 | C3 | instance | calls.rb:338:5:340:7 | instance | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | m1 | calls.rb:419:9:421:11 | m1 | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | m2 | calls.rb:424:5:436:7 | m2 | -| calls.rb:480:1:486:3 | ExtendSingletonMethod | singleton | calls.rb:481:5:483:7 | singleton | -| calls.rb:509:1:513:3 | ProtectedMethodInModule | foo | calls.rb:510:15:512:7 | foo | -| calls.rb:515:1:528:3 | ProtectedMethods | bar | calls.rb:518:15:520:7 | bar | -| calls.rb:515:1:528:3 | ProtectedMethods | baz | calls.rb:522:5:527:7 | baz | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | baz | calls.rb:535:5:538:7 | baz | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | m1 | calls.rb:423:9:425:11 | m1 | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | m2 | calls.rb:428:5:440:7 | m2 | +| calls.rb:484:1:490:3 | ExtendSingletonMethod | singleton | calls.rb:485:5:487:7 | singleton | +| calls.rb:513:1:517:3 | ProtectedMethodInModule | foo | calls.rb:514:15:516:7 | foo | +| calls.rb:519:1:532:3 | ProtectedMethods | bar | calls.rb:522:15:524:7 | bar | +| calls.rb:519:1:532:3 | ProtectedMethods | baz | calls.rb:526:5:531:7 | baz | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | baz | calls.rb:539:5:542:7 | baz | | hello.rb:1:1:8:3 | EnglishWords | hello | hello.rb:2:5:4:7 | hello | | hello.rb:1:1:8:3 | EnglishWords | world | hello.rb:5:5:7:7 | world | | hello.rb:11:1:16:3 | Greeting | message | hello.rb:13:5:15:7 | message | @@ -326,68 +326,68 @@ lookupMethod | calls.rb:377:1:397:3 | SingletonOverride1 | private_on_main | calls.rb:185:1:186:3 | private_on_main | | calls.rb:377:1:397:3 | SingletonOverride1 | puts | calls.rb:102:5:102:30 | puts | | calls.rb:377:1:397:3 | SingletonOverride1 | to_s | calls.rb:172:5:173:7 | to_s | -| calls.rb:402:1:412:3 | SingletonOverride2 | add_singleton | calls.rb:367:1:371:3 | add_singleton | -| calls.rb:402:1:412:3 | SingletonOverride2 | call_block | calls.rb:81:1:83:3 | call_block | -| calls.rb:402:1:412:3 | SingletonOverride2 | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | -| calls.rb:402:1:412:3 | SingletonOverride2 | create | calls.rb:278:1:286:3 | create | -| calls.rb:402:1:412:3 | SingletonOverride2 | foo | calls.rb:1:1:3:3 | foo | -| calls.rb:402:1:412:3 | SingletonOverride2 | foo | calls.rb:85:1:89:3 | foo | -| calls.rb:402:1:412:3 | SingletonOverride2 | funny | calls.rb:140:1:142:3 | funny | -| calls.rb:402:1:412:3 | SingletonOverride2 | indirect | calls.rb:158:1:160:3 | indirect | -| calls.rb:402:1:412:3 | SingletonOverride2 | new | calls.rb:117:5:117:16 | new | -| calls.rb:402:1:412:3 | SingletonOverride2 | optional_arg | calls.rb:76:1:79:3 | optional_arg | -| calls.rb:402:1:412:3 | SingletonOverride2 | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | -| calls.rb:402:1:412:3 | SingletonOverride2 | private_on_main | calls.rb:185:1:186:3 | private_on_main | -| calls.rb:402:1:412:3 | SingletonOverride2 | puts | calls.rb:102:5:102:30 | puts | -| calls.rb:402:1:412:3 | SingletonOverride2 | to_s | calls.rb:172:5:173:7 | to_s | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | add_singleton | calls.rb:367:1:371:3 | add_singleton | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | call_block | calls.rb:81:1:83:3 | call_block | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | create | calls.rb:278:1:286:3 | create | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | foo | calls.rb:1:1:3:3 | foo | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | foo | calls.rb:85:1:89:3 | foo | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | funny | calls.rb:140:1:142:3 | funny | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | indirect | calls.rb:158:1:160:3 | indirect | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | m1 | calls.rb:419:9:421:11 | m1 | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | m2 | calls.rb:424:5:436:7 | m2 | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | new | calls.rb:117:5:117:16 | new | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | optional_arg | calls.rb:76:1:79:3 | optional_arg | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | private_on_main | calls.rb:185:1:186:3 | private_on_main | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | puts | calls.rb:102:5:102:30 | puts | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | to_s | calls.rb:172:5:173:7 | to_s | -| calls.rb:480:1:486:3 | ExtendSingletonMethod | singleton | calls.rb:481:5:483:7 | singleton | -| calls.rb:509:1:513:3 | ProtectedMethodInModule | foo | calls.rb:510:15:512:7 | foo | -| calls.rb:515:1:528:3 | ProtectedMethods | add_singleton | calls.rb:367:1:371:3 | add_singleton | -| calls.rb:515:1:528:3 | ProtectedMethods | bar | calls.rb:518:15:520:7 | bar | -| calls.rb:515:1:528:3 | ProtectedMethods | baz | calls.rb:522:5:527:7 | baz | -| calls.rb:515:1:528:3 | ProtectedMethods | call_block | calls.rb:81:1:83:3 | call_block | -| calls.rb:515:1:528:3 | ProtectedMethods | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | -| calls.rb:515:1:528:3 | ProtectedMethods | create | calls.rb:278:1:286:3 | create | -| calls.rb:515:1:528:3 | ProtectedMethods | foo | calls.rb:510:15:512:7 | foo | -| calls.rb:515:1:528:3 | ProtectedMethods | funny | calls.rb:140:1:142:3 | funny | -| calls.rb:515:1:528:3 | ProtectedMethods | indirect | calls.rb:158:1:160:3 | indirect | -| calls.rb:515:1:528:3 | ProtectedMethods | new | calls.rb:117:5:117:16 | new | -| calls.rb:515:1:528:3 | ProtectedMethods | optional_arg | calls.rb:76:1:79:3 | optional_arg | -| calls.rb:515:1:528:3 | ProtectedMethods | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | -| calls.rb:515:1:528:3 | ProtectedMethods | private_on_main | calls.rb:185:1:186:3 | private_on_main | -| calls.rb:515:1:528:3 | ProtectedMethods | puts | calls.rb:102:5:102:30 | puts | -| calls.rb:515:1:528:3 | ProtectedMethods | to_s | calls.rb:172:5:173:7 | to_s | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | add_singleton | calls.rb:367:1:371:3 | add_singleton | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | bar | calls.rb:518:15:520:7 | bar | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | baz | calls.rb:535:5:538:7 | baz | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | call_block | calls.rb:81:1:83:3 | call_block | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | create | calls.rb:278:1:286:3 | create | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | foo | calls.rb:510:15:512:7 | foo | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | funny | calls.rb:140:1:142:3 | funny | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | indirect | calls.rb:158:1:160:3 | indirect | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | new | calls.rb:117:5:117:16 | new | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | optional_arg | calls.rb:76:1:79:3 | optional_arg | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | private_on_main | calls.rb:185:1:186:3 | private_on_main | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | puts | calls.rb:102:5:102:30 | puts | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | to_s | calls.rb:172:5:173:7 | to_s | +| calls.rb:404:1:414:3 | SingletonOverride2 | add_singleton | calls.rb:367:1:371:3 | add_singleton | +| calls.rb:404:1:414:3 | SingletonOverride2 | call_block | calls.rb:81:1:83:3 | call_block | +| calls.rb:404:1:414:3 | SingletonOverride2 | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | +| calls.rb:404:1:414:3 | SingletonOverride2 | create | calls.rb:278:1:286:3 | create | +| calls.rb:404:1:414:3 | SingletonOverride2 | foo | calls.rb:1:1:3:3 | foo | +| calls.rb:404:1:414:3 | SingletonOverride2 | foo | calls.rb:85:1:89:3 | foo | +| calls.rb:404:1:414:3 | SingletonOverride2 | funny | calls.rb:140:1:142:3 | funny | +| calls.rb:404:1:414:3 | SingletonOverride2 | indirect | calls.rb:158:1:160:3 | indirect | +| calls.rb:404:1:414:3 | SingletonOverride2 | new | calls.rb:117:5:117:16 | new | +| calls.rb:404:1:414:3 | SingletonOverride2 | optional_arg | calls.rb:76:1:79:3 | optional_arg | +| calls.rb:404:1:414:3 | SingletonOverride2 | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | +| calls.rb:404:1:414:3 | SingletonOverride2 | private_on_main | calls.rb:185:1:186:3 | private_on_main | +| calls.rb:404:1:414:3 | SingletonOverride2 | puts | calls.rb:102:5:102:30 | puts | +| calls.rb:404:1:414:3 | SingletonOverride2 | to_s | calls.rb:172:5:173:7 | to_s | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | add_singleton | calls.rb:367:1:371:3 | add_singleton | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | call_block | calls.rb:81:1:83:3 | call_block | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | create | calls.rb:278:1:286:3 | create | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | foo | calls.rb:1:1:3:3 | foo | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | foo | calls.rb:85:1:89:3 | foo | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | funny | calls.rb:140:1:142:3 | funny | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | indirect | calls.rb:158:1:160:3 | indirect | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | m1 | calls.rb:423:9:425:11 | m1 | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | m2 | calls.rb:428:5:440:7 | m2 | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | new | calls.rb:117:5:117:16 | new | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | optional_arg | calls.rb:76:1:79:3 | optional_arg | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | private_on_main | calls.rb:185:1:186:3 | private_on_main | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | puts | calls.rb:102:5:102:30 | puts | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | to_s | calls.rb:172:5:173:7 | to_s | +| calls.rb:484:1:490:3 | ExtendSingletonMethod | singleton | calls.rb:485:5:487:7 | singleton | +| calls.rb:513:1:517:3 | ProtectedMethodInModule | foo | calls.rb:514:15:516:7 | foo | +| calls.rb:519:1:532:3 | ProtectedMethods | add_singleton | calls.rb:367:1:371:3 | add_singleton | +| calls.rb:519:1:532:3 | ProtectedMethods | bar | calls.rb:522:15:524:7 | bar | +| calls.rb:519:1:532:3 | ProtectedMethods | baz | calls.rb:526:5:531:7 | baz | +| calls.rb:519:1:532:3 | ProtectedMethods | call_block | calls.rb:81:1:83:3 | call_block | +| calls.rb:519:1:532:3 | ProtectedMethods | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | +| calls.rb:519:1:532:3 | ProtectedMethods | create | calls.rb:278:1:286:3 | create | +| calls.rb:519:1:532:3 | ProtectedMethods | foo | calls.rb:514:15:516:7 | foo | +| calls.rb:519:1:532:3 | ProtectedMethods | funny | calls.rb:140:1:142:3 | funny | +| calls.rb:519:1:532:3 | ProtectedMethods | indirect | calls.rb:158:1:160:3 | indirect | +| calls.rb:519:1:532:3 | ProtectedMethods | new | calls.rb:117:5:117:16 | new | +| calls.rb:519:1:532:3 | ProtectedMethods | optional_arg | calls.rb:76:1:79:3 | optional_arg | +| calls.rb:519:1:532:3 | ProtectedMethods | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | +| calls.rb:519:1:532:3 | ProtectedMethods | private_on_main | calls.rb:185:1:186:3 | private_on_main | +| calls.rb:519:1:532:3 | ProtectedMethods | puts | calls.rb:102:5:102:30 | puts | +| calls.rb:519:1:532:3 | ProtectedMethods | to_s | calls.rb:172:5:173:7 | to_s | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | add_singleton | calls.rb:367:1:371:3 | add_singleton | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | bar | calls.rb:522:15:524:7 | bar | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | baz | calls.rb:539:5:542:7 | baz | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | call_block | calls.rb:81:1:83:3 | call_block | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | call_instance_m | calls.rb:39:1:41:3 | call_instance_m | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | create | calls.rb:278:1:286:3 | create | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | foo | calls.rb:514:15:516:7 | foo | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | funny | calls.rb:140:1:142:3 | funny | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | indirect | calls.rb:158:1:160:3 | indirect | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | new | calls.rb:117:5:117:16 | new | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | optional_arg | calls.rb:76:1:79:3 | optional_arg | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | pattern_dispatch | calls.rb:343:1:359:3 | pattern_dispatch | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | private_on_main | calls.rb:185:1:186:3 | private_on_main | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | puts | calls.rb:102:5:102:30 | puts | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | to_s | calls.rb:172:5:173:7 | to_s | | file://:0:0:0:0 | Class | include | calls.rb:108:5:110:7 | include | | file://:0:0:0:0 | Class | module_eval | calls.rb:107:5:107:24 | module_eval | | file://:0:0:0:0 | Class | new | calls.rb:117:5:117:16 | new | @@ -765,73 +765,73 @@ enclosingMethod | calls.rb:389:15:389:43 | SingletonOverride1#singleton2 | calls.rb:388:5:390:7 | singleton2 | | calls.rb:393:9:393:18 | call to singleton2 | calls.rb:392:5:394:7 | call_singleton2 | | calls.rb:393:9:393:18 | self | calls.rb:392:5:394:7 | call_singleton2 | -| calls.rb:405:13:405:48 | call to puts | calls.rb:404:9:406:11 | singleton1 | -| calls.rb:405:13:405:48 | self | calls.rb:404:9:406:11 | singleton1 | -| calls.rb:405:18:405:48 | "SingletonOverride2#singleton1" | calls.rb:404:9:406:11 | singleton1 | -| calls.rb:405:19:405:47 | SingletonOverride2#singleton1 | calls.rb:404:9:406:11 | singleton1 | -| calls.rb:410:9:410:44 | call to puts | calls.rb:409:5:411:7 | singleton2 | -| calls.rb:410:9:410:44 | self | calls.rb:409:5:411:7 | singleton2 | -| calls.rb:410:14:410:44 | "SingletonOverride2#singleton2" | calls.rb:409:5:411:7 | singleton2 | -| calls.rb:410:15:410:43 | SingletonOverride2#singleton2 | calls.rb:409:5:411:7 | singleton2 | -| calls.rb:420:13:420:48 | call to puts | calls.rb:419:9:421:11 | m1 | -| calls.rb:420:13:420:48 | self | calls.rb:419:9:421:11 | m1 | -| calls.rb:420:18:420:48 | "ConditionalInstanceMethods#m1" | calls.rb:419:9:421:11 | m1 | -| calls.rb:420:19:420:47 | ConditionalInstanceMethods#m1 | calls.rb:419:9:421:11 | m1 | -| calls.rb:425:9:425:44 | call to puts | calls.rb:424:5:436:7 | m2 | -| calls.rb:425:9:425:44 | self | calls.rb:424:5:436:7 | m2 | -| calls.rb:425:14:425:44 | "ConditionalInstanceMethods#m2" | calls.rb:424:5:436:7 | m2 | -| calls.rb:425:15:425:43 | ConditionalInstanceMethods#m2 | calls.rb:424:5:436:7 | m2 | -| calls.rb:427:9:433:11 | m3 | calls.rb:424:5:436:7 | m2 | -| calls.rb:428:13:428:48 | call to puts | calls.rb:427:9:433:11 | m3 | -| calls.rb:428:13:428:48 | self | calls.rb:427:9:433:11 | m3 | -| calls.rb:428:18:428:48 | "ConditionalInstanceMethods#m3" | calls.rb:427:9:433:11 | m3 | -| calls.rb:428:19:428:47 | ConditionalInstanceMethods#m3 | calls.rb:427:9:433:11 | m3 | -| calls.rb:430:13:432:15 | m4 | calls.rb:427:9:433:11 | m3 | -| calls.rb:431:17:431:52 | call to puts | calls.rb:430:13:432:15 | m4 | -| calls.rb:431:17:431:52 | self | calls.rb:430:13:432:15 | m4 | -| calls.rb:431:22:431:52 | "ConditionalInstanceMethods#m4" | calls.rb:430:13:432:15 | m4 | -| calls.rb:431:23:431:51 | ConditionalInstanceMethods#m4 | calls.rb:430:13:432:15 | m4 | -| calls.rb:435:9:435:10 | call to m3 | calls.rb:424:5:436:7 | m2 | -| calls.rb:435:9:435:10 | self | calls.rb:424:5:436:7 | m2 | -| calls.rb:441:17:441:40 | call to puts | calls.rb:440:13:442:15 | m5 | -| calls.rb:441:17:441:40 | self | calls.rb:440:13:442:15 | m5 | -| calls.rb:441:22:441:40 | "AnonymousClass#m5" | calls.rb:440:13:442:15 | m5 | -| calls.rb:441:23:441:39 | AnonymousClass#m5 | calls.rb:440:13:442:15 | m5 | -| calls.rb:457:13:457:22 | call to puts | calls.rb:456:9:458:11 | foo | -| calls.rb:457:13:457:22 | self | calls.rb:456:9:458:11 | foo | -| calls.rb:457:18:457:22 | "foo" | calls.rb:456:9:458:11 | foo | -| calls.rb:457:19:457:21 | foo | calls.rb:456:9:458:11 | foo | -| calls.rb:463:13:463:22 | call to puts | calls.rb:462:9:464:11 | bar | -| calls.rb:463:13:463:22 | self | calls.rb:462:9:464:11 | bar | -| calls.rb:463:18:463:22 | "bar" | calls.rb:462:9:464:11 | bar | -| calls.rb:463:19:463:21 | bar | calls.rb:462:9:464:11 | bar | -| calls.rb:482:9:482:46 | call to puts | calls.rb:481:5:483:7 | singleton | -| calls.rb:482:9:482:46 | self | calls.rb:481:5:483:7 | singleton | -| calls.rb:482:14:482:46 | "ExtendSingletonMethod#singleton" | calls.rb:481:5:483:7 | singleton | -| calls.rb:482:15:482:45 | ExtendSingletonMethod#singleton | calls.rb:481:5:483:7 | singleton | -| calls.rb:511:9:511:42 | call to puts | calls.rb:510:15:512:7 | foo | -| calls.rb:511:9:511:42 | self | calls.rb:510:15:512:7 | foo | -| calls.rb:511:14:511:42 | "ProtectedMethodInModule#foo" | calls.rb:510:15:512:7 | foo | -| calls.rb:511:15:511:41 | ProtectedMethodInModule#foo | calls.rb:510:15:512:7 | foo | -| calls.rb:519:9:519:35 | call to puts | calls.rb:518:15:520:7 | bar | -| calls.rb:519:9:519:35 | self | calls.rb:518:15:520:7 | bar | -| calls.rb:519:14:519:35 | "ProtectedMethods#bar" | calls.rb:518:15:520:7 | bar | -| calls.rb:519:15:519:34 | ProtectedMethods#bar | calls.rb:518:15:520:7 | bar | -| calls.rb:523:9:523:11 | call to foo | calls.rb:522:5:527:7 | baz | -| calls.rb:523:9:523:11 | self | calls.rb:522:5:527:7 | baz | -| calls.rb:524:9:524:11 | call to bar | calls.rb:522:5:527:7 | baz | -| calls.rb:524:9:524:11 | self | calls.rb:522:5:527:7 | baz | -| calls.rb:525:9:525:24 | ProtectedMethods | calls.rb:522:5:527:7 | baz | -| calls.rb:525:9:525:28 | call to new | calls.rb:522:5:527:7 | baz | -| calls.rb:525:9:525:32 | call to foo | calls.rb:522:5:527:7 | baz | -| calls.rb:526:9:526:24 | ProtectedMethods | calls.rb:522:5:527:7 | baz | -| calls.rb:526:9:526:28 | call to new | calls.rb:522:5:527:7 | baz | -| calls.rb:526:9:526:32 | call to bar | calls.rb:522:5:527:7 | baz | -| calls.rb:536:9:536:11 | call to foo | calls.rb:535:5:538:7 | baz | -| calls.rb:536:9:536:11 | self | calls.rb:535:5:538:7 | baz | -| calls.rb:537:9:537:27 | ProtectedMethodsSub | calls.rb:535:5:538:7 | baz | -| calls.rb:537:9:537:31 | call to new | calls.rb:535:5:538:7 | baz | -| calls.rb:537:9:537:35 | call to foo | calls.rb:535:5:538:7 | baz | +| calls.rb:407:13:407:48 | call to puts | calls.rb:406:9:408:11 | singleton1 | +| calls.rb:407:13:407:48 | self | calls.rb:406:9:408:11 | singleton1 | +| calls.rb:407:18:407:48 | "SingletonOverride2#singleton1" | calls.rb:406:9:408:11 | singleton1 | +| calls.rb:407:19:407:47 | SingletonOverride2#singleton1 | calls.rb:406:9:408:11 | singleton1 | +| calls.rb:412:9:412:44 | call to puts | calls.rb:411:5:413:7 | singleton2 | +| calls.rb:412:9:412:44 | self | calls.rb:411:5:413:7 | singleton2 | +| calls.rb:412:14:412:44 | "SingletonOverride2#singleton2" | calls.rb:411:5:413:7 | singleton2 | +| calls.rb:412:15:412:43 | SingletonOverride2#singleton2 | calls.rb:411:5:413:7 | singleton2 | +| calls.rb:424:13:424:48 | call to puts | calls.rb:423:9:425:11 | m1 | +| calls.rb:424:13:424:48 | self | calls.rb:423:9:425:11 | m1 | +| calls.rb:424:18:424:48 | "ConditionalInstanceMethods#m1" | calls.rb:423:9:425:11 | m1 | +| calls.rb:424:19:424:47 | ConditionalInstanceMethods#m1 | calls.rb:423:9:425:11 | m1 | +| calls.rb:429:9:429:44 | call to puts | calls.rb:428:5:440:7 | m2 | +| calls.rb:429:9:429:44 | self | calls.rb:428:5:440:7 | m2 | +| calls.rb:429:14:429:44 | "ConditionalInstanceMethods#m2" | calls.rb:428:5:440:7 | m2 | +| calls.rb:429:15:429:43 | ConditionalInstanceMethods#m2 | calls.rb:428:5:440:7 | m2 | +| calls.rb:431:9:437:11 | m3 | calls.rb:428:5:440:7 | m2 | +| calls.rb:432:13:432:48 | call to puts | calls.rb:431:9:437:11 | m3 | +| calls.rb:432:13:432:48 | self | calls.rb:431:9:437:11 | m3 | +| calls.rb:432:18:432:48 | "ConditionalInstanceMethods#m3" | calls.rb:431:9:437:11 | m3 | +| calls.rb:432:19:432:47 | ConditionalInstanceMethods#m3 | calls.rb:431:9:437:11 | m3 | +| calls.rb:434:13:436:15 | m4 | calls.rb:431:9:437:11 | m3 | +| calls.rb:435:17:435:52 | call to puts | calls.rb:434:13:436:15 | m4 | +| calls.rb:435:17:435:52 | self | calls.rb:434:13:436:15 | m4 | +| calls.rb:435:22:435:52 | "ConditionalInstanceMethods#m4" | calls.rb:434:13:436:15 | m4 | +| calls.rb:435:23:435:51 | ConditionalInstanceMethods#m4 | calls.rb:434:13:436:15 | m4 | +| calls.rb:439:9:439:10 | call to m3 | calls.rb:428:5:440:7 | m2 | +| calls.rb:439:9:439:10 | self | calls.rb:428:5:440:7 | m2 | +| calls.rb:445:17:445:40 | call to puts | calls.rb:444:13:446:15 | m5 | +| calls.rb:445:17:445:40 | self | calls.rb:444:13:446:15 | m5 | +| calls.rb:445:22:445:40 | "AnonymousClass#m5" | calls.rb:444:13:446:15 | m5 | +| calls.rb:445:23:445:39 | AnonymousClass#m5 | calls.rb:444:13:446:15 | m5 | +| calls.rb:461:13:461:22 | call to puts | calls.rb:460:9:462:11 | foo | +| calls.rb:461:13:461:22 | self | calls.rb:460:9:462:11 | foo | +| calls.rb:461:18:461:22 | "foo" | calls.rb:460:9:462:11 | foo | +| calls.rb:461:19:461:21 | foo | calls.rb:460:9:462:11 | foo | +| calls.rb:467:13:467:22 | call to puts | calls.rb:466:9:468:11 | bar | +| calls.rb:467:13:467:22 | self | calls.rb:466:9:468:11 | bar | +| calls.rb:467:18:467:22 | "bar" | calls.rb:466:9:468:11 | bar | +| calls.rb:467:19:467:21 | bar | calls.rb:466:9:468:11 | bar | +| calls.rb:486:9:486:46 | call to puts | calls.rb:485:5:487:7 | singleton | +| calls.rb:486:9:486:46 | self | calls.rb:485:5:487:7 | singleton | +| calls.rb:486:14:486:46 | "ExtendSingletonMethod#singleton" | calls.rb:485:5:487:7 | singleton | +| calls.rb:486:15:486:45 | ExtendSingletonMethod#singleton | calls.rb:485:5:487:7 | singleton | +| calls.rb:515:9:515:42 | call to puts | calls.rb:514:15:516:7 | foo | +| calls.rb:515:9:515:42 | self | calls.rb:514:15:516:7 | foo | +| calls.rb:515:14:515:42 | "ProtectedMethodInModule#foo" | calls.rb:514:15:516:7 | foo | +| calls.rb:515:15:515:41 | ProtectedMethodInModule#foo | calls.rb:514:15:516:7 | foo | +| calls.rb:523:9:523:35 | call to puts | calls.rb:522:15:524:7 | bar | +| calls.rb:523:9:523:35 | self | calls.rb:522:15:524:7 | bar | +| calls.rb:523:14:523:35 | "ProtectedMethods#bar" | calls.rb:522:15:524:7 | bar | +| calls.rb:523:15:523:34 | ProtectedMethods#bar | calls.rb:522:15:524:7 | bar | +| calls.rb:527:9:527:11 | call to foo | calls.rb:526:5:531:7 | baz | +| calls.rb:527:9:527:11 | self | calls.rb:526:5:531:7 | baz | +| calls.rb:528:9:528:11 | call to bar | calls.rb:526:5:531:7 | baz | +| calls.rb:528:9:528:11 | self | calls.rb:526:5:531:7 | baz | +| calls.rb:529:9:529:24 | ProtectedMethods | calls.rb:526:5:531:7 | baz | +| calls.rb:529:9:529:28 | call to new | calls.rb:526:5:531:7 | baz | +| calls.rb:529:9:529:32 | call to foo | calls.rb:526:5:531:7 | baz | +| calls.rb:530:9:530:24 | ProtectedMethods | calls.rb:526:5:531:7 | baz | +| calls.rb:530:9:530:28 | call to new | calls.rb:526:5:531:7 | baz | +| calls.rb:530:9:530:32 | call to bar | calls.rb:526:5:531:7 | baz | +| calls.rb:540:9:540:11 | call to foo | calls.rb:539:5:542:7 | baz | +| calls.rb:540:9:540:11 | self | calls.rb:539:5:542:7 | baz | +| calls.rb:541:9:541:27 | ProtectedMethodsSub | calls.rb:539:5:542:7 | baz | +| calls.rb:541:9:541:31 | call to new | calls.rb:539:5:542:7 | baz | +| calls.rb:541:9:541:35 | call to foo | calls.rb:539:5:542:7 | baz | | hello.rb:3:9:3:22 | return | hello.rb:2:5:4:7 | hello | | hello.rb:3:16:3:22 | "hello" | hello.rb:2:5:4:7 | hello | | hello.rb:3:17:3:21 | hello | hello.rb:2:5:4:7 | hello | diff --git a/ruby/ql/test/library-tests/modules/modules.expected b/ruby/ql/test/library-tests/modules/modules.expected index 2ef6ed4405c..93bcb04aec5 100644 --- a/ruby/ql/test/library-tests/modules/modules.expected +++ b/ruby/ql/test/library-tests/modules/modules.expected @@ -18,14 +18,14 @@ getModule | calls.rb:331:1:335:3 | C2 | | calls.rb:337:1:341:3 | C3 | | calls.rb:377:1:397:3 | SingletonOverride1 | -| calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:490:1:492:3 | ExtendSingletonMethod2 | -| calls.rb:496:1:497:3 | ExtendSingletonMethod3 | -| calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | +| calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:494:1:496:3 | ExtendSingletonMethod2 | +| calls.rb:500:1:501:3 | ExtendSingletonMethod3 | +| calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | | file://:0:0:0:0 | BasicObject | | file://:0:0:0:0 | Class | | file://:0:0:0:0 | Complex | @@ -84,7 +84,7 @@ getADeclaration | calls.rb:96:1:98:3 | String | calls.rb:96:1:98:3 | String | | calls.rb:100:1:103:3 | Kernel | calls.rb:100:1:103:3 | Kernel | | calls.rb:105:1:113:3 | Module | calls.rb:105:1:113:3 | Module | -| calls.rb:115:1:118:3 | Object | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:115:1:118:3 | Object | calls.rb:1:1:550:40 | calls.rb | | calls.rb:115:1:118:3 | Object | calls.rb:115:1:118:3 | Object | | calls.rb:115:1:118:3 | Object | hello.rb:1:1:22:3 | hello.rb | | calls.rb:115:1:118:3 | Object | modules.rb:1:1:129:4 | modules.rb | @@ -102,14 +102,14 @@ getADeclaration | calls.rb:331:1:335:3 | C2 | calls.rb:331:1:335:3 | C2 | | calls.rb:337:1:341:3 | C3 | calls.rb:337:1:341:3 | C3 | | calls.rb:377:1:397:3 | SingletonOverride1 | calls.rb:377:1:397:3 | SingletonOverride1 | -| calls.rb:402:1:412:3 | SingletonOverride2 | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:480:1:486:3 | ExtendSingletonMethod | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:490:1:492:3 | ExtendSingletonMethod2 | calls.rb:490:1:492:3 | ExtendSingletonMethod2 | -| calls.rb:496:1:497:3 | ExtendSingletonMethod3 | calls.rb:496:1:497:3 | ExtendSingletonMethod3 | -| calls.rb:509:1:513:3 | ProtectedMethodInModule | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:515:1:528:3 | ProtectedMethods | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | calls.rb:534:1:539:3 | ProtectedMethodsSub | +| calls.rb:404:1:414:3 | SingletonOverride2 | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:484:1:490:3 | ExtendSingletonMethod | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:494:1:496:3 | ExtendSingletonMethod2 | calls.rb:494:1:496:3 | ExtendSingletonMethod2 | +| calls.rb:500:1:501:3 | ExtendSingletonMethod3 | calls.rb:500:1:501:3 | ExtendSingletonMethod3 | +| calls.rb:513:1:517:3 | ProtectedMethodInModule | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:519:1:532:3 | ProtectedMethods | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | calls.rb:538:1:543:3 | ProtectedMethodsSub | | hello.rb:1:1:8:3 | EnglishWords | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:11:1:16:3 | Greeting | hello.rb:11:1:16:3 | Greeting | | hello.rb:18:1:22:3 | HelloWorld | hello.rb:18:1:22:3 | HelloWorld | @@ -171,10 +171,10 @@ getSuperClass | calls.rb:331:1:335:3 | C2 | calls.rb:325:1:329:3 | C1 | | calls.rb:337:1:341:3 | C3 | calls.rb:331:1:335:3 | C2 | | calls.rb:377:1:397:3 | SingletonOverride1 | calls.rb:115:1:118:3 | Object | -| calls.rb:402:1:412:3 | SingletonOverride2 | calls.rb:377:1:397:3 | SingletonOverride1 | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | calls.rb:115:1:118:3 | Object | -| calls.rb:515:1:528:3 | ProtectedMethods | calls.rb:115:1:118:3 | Object | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | calls.rb:515:1:528:3 | ProtectedMethods | +| calls.rb:404:1:414:3 | SingletonOverride2 | calls.rb:377:1:397:3 | SingletonOverride1 | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | calls.rb:115:1:118:3 | Object | +| calls.rb:519:1:532:3 | ProtectedMethods | calls.rb:115:1:118:3 | Object | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | calls.rb:519:1:532:3 | ProtectedMethods | | file://:0:0:0:0 | Class | calls.rb:105:1:113:3 | Module | | file://:0:0:0:0 | Complex | file://:0:0:0:0 | Numeric | | file://:0:0:0:0 | FalseClass | calls.rb:115:1:118:3 | Object | @@ -206,7 +206,7 @@ getAPrependedModule getAnIncludedModule | calls.rb:43:1:58:3 | C | calls.rb:21:1:34:3 | M | | calls.rb:115:1:118:3 | Object | calls.rb:100:1:103:3 | Kernel | -| calls.rb:515:1:528:3 | ProtectedMethods | calls.rb:509:1:513:3 | ProtectedMethodInModule | +| calls.rb:519:1:532:3 | ProtectedMethods | calls.rb:513:1:517:3 | ProtectedMethodInModule | | hello.rb:11:1:16:3 | Greeting | hello.rb:1:1:8:3 | EnglishWords | | modules.rb:88:1:93:3 | IncludeTest | modules.rb:63:1:81:3 | Test | | modules.rb:95:1:99:3 | IncludeTest2 | modules.rb:63:1:81:3 | Test | @@ -258,41 +258,45 @@ resolveConstantReadAccess | calls.rb:373:6:373:7 | C1 | C1 | | calls.rb:399:1:399:18 | SingletonOverride1 | SingletonOverride1 | | calls.rb:400:1:400:18 | SingletonOverride1 | SingletonOverride1 | -| calls.rb:402:28:402:45 | SingletonOverride1 | SingletonOverride1 | -| calls.rb:414:1:414:18 | SingletonOverride2 | SingletonOverride2 | -| calls.rb:415:1:415:18 | SingletonOverride2 | SingletonOverride2 | -| calls.rb:439:9:439:13 | Class | Class | -| calls.rb:447:1:447:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | -| calls.rb:448:1:448:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | -| calls.rb:449:1:449:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | -| calls.rb:450:1:450:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | +| calls.rb:401:1:401:18 | SingletonOverride1 | SingletonOverride1 | +| calls.rb:402:1:402:18 | SingletonOverride1 | SingletonOverride1 | +| calls.rb:404:28:404:45 | SingletonOverride1 | SingletonOverride1 | +| calls.rb:416:1:416:18 | SingletonOverride2 | SingletonOverride2 | +| calls.rb:417:1:417:18 | SingletonOverride2 | SingletonOverride2 | +| calls.rb:418:1:418:18 | SingletonOverride2 | SingletonOverride2 | +| calls.rb:419:1:419:18 | SingletonOverride2 | SingletonOverride2 | +| calls.rb:443:9:443:13 | Class | Class | | calls.rb:451:1:451:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | | calls.rb:452:1:452:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | -| calls.rb:454:27:454:31 | Class | Class | -| calls.rb:455:5:455:11 | Array | Array | -| calls.rb:461:5:461:9 | Class | Class | -| calls.rb:467:5:467:11 | Array | Array | -| calls.rb:488:1:488:21 | ExtendSingletonMethod | ExtendSingletonMethod | -| calls.rb:491:12:491:32 | ExtendSingletonMethod | ExtendSingletonMethod | -| calls.rb:494:1:494:22 | ExtendSingletonMethod2 | ExtendSingletonMethod2 | -| calls.rb:499:1:499:22 | ExtendSingletonMethod3 | ExtendSingletonMethod3 | -| calls.rb:499:31:499:51 | ExtendSingletonMethod | ExtendSingletonMethod | -| calls.rb:501:1:501:22 | ExtendSingletonMethod3 | ExtendSingletonMethod3 | -| calls.rb:505:12:505:32 | ExtendSingletonMethod | ExtendSingletonMethod | -| calls.rb:516:13:516:35 | ProtectedMethodInModule | ProtectedMethodInModule | -| calls.rb:525:9:525:24 | ProtectedMethods | ProtectedMethods | -| calls.rb:526:9:526:24 | ProtectedMethods | ProtectedMethods | -| calls.rb:530:1:530:16 | ProtectedMethods | ProtectedMethods | -| calls.rb:531:1:531:16 | ProtectedMethods | ProtectedMethods | -| calls.rb:532:1:532:16 | ProtectedMethods | ProtectedMethods | -| calls.rb:534:29:534:44 | ProtectedMethods | ProtectedMethods | -| calls.rb:537:9:537:27 | ProtectedMethodsSub | ProtectedMethodsSub | -| calls.rb:541:1:541:19 | ProtectedMethodsSub | ProtectedMethodsSub | -| calls.rb:542:1:542:19 | ProtectedMethodsSub | ProtectedMethodsSub | -| calls.rb:543:1:543:19 | ProtectedMethodsSub | ProtectedMethodsSub | -| calls.rb:545:1:545:7 | Array | Array | -| calls.rb:545:2:545:2 | C | C | -| calls.rb:546:1:546:13 | Array | Array | +| calls.rb:453:1:453:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | +| calls.rb:454:1:454:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | +| calls.rb:455:1:455:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | +| calls.rb:456:1:456:26 | ConditionalInstanceMethods | ConditionalInstanceMethods | +| calls.rb:458:27:458:31 | Class | Class | +| calls.rb:459:5:459:11 | Array | Array | +| calls.rb:465:5:465:9 | Class | Class | +| calls.rb:471:5:471:11 | Array | Array | +| calls.rb:492:1:492:21 | ExtendSingletonMethod | ExtendSingletonMethod | +| calls.rb:495:12:495:32 | ExtendSingletonMethod | ExtendSingletonMethod | +| calls.rb:498:1:498:22 | ExtendSingletonMethod2 | ExtendSingletonMethod2 | +| calls.rb:503:1:503:22 | ExtendSingletonMethod3 | ExtendSingletonMethod3 | +| calls.rb:503:31:503:51 | ExtendSingletonMethod | ExtendSingletonMethod | +| calls.rb:505:1:505:22 | ExtendSingletonMethod3 | ExtendSingletonMethod3 | +| calls.rb:509:12:509:32 | ExtendSingletonMethod | ExtendSingletonMethod | +| calls.rb:520:13:520:35 | ProtectedMethodInModule | ProtectedMethodInModule | +| calls.rb:529:9:529:24 | ProtectedMethods | ProtectedMethods | +| calls.rb:530:9:530:24 | ProtectedMethods | ProtectedMethods | +| calls.rb:534:1:534:16 | ProtectedMethods | ProtectedMethods | +| calls.rb:535:1:535:16 | ProtectedMethods | ProtectedMethods | +| calls.rb:536:1:536:16 | ProtectedMethods | ProtectedMethods | +| calls.rb:538:29:538:44 | ProtectedMethods | ProtectedMethods | +| calls.rb:541:9:541:27 | ProtectedMethodsSub | ProtectedMethodsSub | +| calls.rb:545:1:545:19 | ProtectedMethodsSub | ProtectedMethodsSub | +| calls.rb:546:1:546:19 | ProtectedMethodsSub | ProtectedMethodsSub | +| calls.rb:547:1:547:19 | ProtectedMethodsSub | ProtectedMethodsSub | +| calls.rb:549:1:549:7 | Array | Array | +| calls.rb:549:2:549:2 | C | C | +| calls.rb:550:1:550:13 | Array | Array | | hello.rb:12:13:12:24 | EnglishWords | EnglishWords | | hello.rb:18:20:18:27 | Greeting | Greeting | | modules.rb:48:8:48:10 | Foo | Foo | @@ -348,15 +352,15 @@ resolveConstantWriteAccess | calls.rb:331:1:335:3 | C2 | C2 | | calls.rb:337:1:341:3 | C3 | C3 | | calls.rb:377:1:397:3 | SingletonOverride1 | SingletonOverride1 | -| calls.rb:402:1:412:3 | SingletonOverride2 | SingletonOverride2 | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | ConditionalInstanceMethods | -| calls.rb:454:1:454:23 | EsotericInstanceMethods | EsotericInstanceMethods | -| calls.rb:480:1:486:3 | ExtendSingletonMethod | ExtendSingletonMethod | -| calls.rb:490:1:492:3 | ExtendSingletonMethod2 | ExtendSingletonMethod2 | -| calls.rb:496:1:497:3 | ExtendSingletonMethod3 | ExtendSingletonMethod3 | -| calls.rb:509:1:513:3 | ProtectedMethodInModule | ProtectedMethodInModule | -| calls.rb:515:1:528:3 | ProtectedMethods | ProtectedMethods | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | ProtectedMethodsSub | +| calls.rb:404:1:414:3 | SingletonOverride2 | SingletonOverride2 | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | ConditionalInstanceMethods | +| calls.rb:458:1:458:23 | EsotericInstanceMethods | EsotericInstanceMethods | +| calls.rb:484:1:490:3 | ExtendSingletonMethod | ExtendSingletonMethod | +| calls.rb:494:1:496:3 | ExtendSingletonMethod2 | ExtendSingletonMethod2 | +| calls.rb:500:1:501:3 | ExtendSingletonMethod3 | ExtendSingletonMethod3 | +| calls.rb:513:1:517:3 | ProtectedMethodInModule | ProtectedMethodInModule | +| calls.rb:519:1:532:3 | ProtectedMethods | ProtectedMethods | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | ProtectedMethodsSub | | hello.rb:1:1:8:3 | EnglishWords | EnglishWords | | hello.rb:11:1:16:3 | Greeting | Greeting | | hello.rb:18:1:22:3 | HelloWorld | HelloWorld | @@ -411,32 +415,32 @@ resolveConstantWriteAccess | private.rb:82:1:94:3 | PrivateOverride1 | PrivateOverride1 | | private.rb:96:1:102:3 | PrivateOverride2 | PrivateOverride2 | enclosingModule -| calls.rb:1:1:3:3 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:2:5:2:14 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:2:5:2:14 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:2:10:2:14 | "foo" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:2:11:2:13 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:5:1:5:3 | call to foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:5:1:5:3 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:7:1:9:3 | bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:7:5:7:8 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:8:5:8:15 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:8:5:8:15 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:8:10:8:15 | "bar1" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:8:11:8:14 | bar1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:11:1:11:4 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:11:1:11:8 | call to bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:13:1:15:3 | bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:13:5:13:8 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:14:5:14:15 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:14:5:14:15 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:14:10:14:15 | "bar2" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:14:11:14:14 | bar2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:17:1:17:4 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:17:1:17:8 | call to bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:19:1:19:4 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:19:1:19:8 | call to foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:21:1:34:3 | M | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:1:1:3:3 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:2:5:2:14 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:2:5:2:14 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:2:10:2:14 | "foo" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:2:11:2:13 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:5:1:5:3 | call to foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:5:1:5:3 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:7:1:9:3 | bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:7:5:7:8 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:8:5:8:15 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:8:5:8:15 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:8:10:8:15 | "bar1" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:8:11:8:14 | bar1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:11:1:11:4 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:11:1:11:8 | call to bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:13:1:15:3 | bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:13:5:13:8 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:14:5:14:15 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:14:5:14:15 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:14:10:14:15 | "bar2" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:14:11:14:14 | bar2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:17:1:17:4 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:17:1:17:8 | call to bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:19:1:19:4 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:19:1:19:8 | call to foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:21:1:34:3 | M | calls.rb:1:1:550:40 | calls.rb | | calls.rb:22:5:24:7 | instance_m | calls.rb:21:1:34:3 | M | | calls.rb:23:9:23:19 | call to singleton_m | calls.rb:21:1:34:3 | M | | calls.rb:23:9:23:19 | self | calls.rb:21:1:34:3 | M | @@ -452,14 +456,14 @@ enclosingModule | calls.rb:32:5:32:15 | self | calls.rb:21:1:34:3 | M | | calls.rb:33:5:33:8 | self | calls.rb:21:1:34:3 | M | | calls.rb:33:5:33:20 | call to singleton_m | calls.rb:21:1:34:3 | M | -| calls.rb:36:1:36:1 | M | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:36:1:36:12 | call to instance_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:37:1:37:1 | M | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:37:1:37:13 | call to singleton_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:39:1:41:3 | call_instance_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:40:5:40:14 | call to instance_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:40:5:40:14 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:43:1:58:3 | C | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:36:1:36:1 | M | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:36:1:36:12 | call to instance_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:37:1:37:1 | M | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:37:1:37:13 | call to singleton_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:39:1:41:3 | call_instance_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:40:5:40:14 | call to instance_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:40:5:40:14 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:43:1:58:3 | C | calls.rb:1:1:550:40 | calls.rb | | calls.rb:44:5:44:13 | call to include | calls.rb:43:1:58:3 | C | | calls.rb:44:5:44:13 | self | calls.rb:43:1:58:3 | C | | calls.rb:44:13:44:13 | M | calls.rb:43:1:58:3 | C | @@ -480,66 +484,66 @@ enclosingModule | calls.rb:55:9:55:19 | self | calls.rb:43:1:58:3 | C | | calls.rb:56:9:56:12 | self | calls.rb:43:1:58:3 | C | | calls.rb:56:9:56:24 | call to singleton_m | calls.rb:43:1:58:3 | C | -| calls.rb:60:1:60:1 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:60:1:60:9 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:60:5:60:5 | C | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:60:5:60:9 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:61:1:61:1 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:61:1:61:5 | call to baz | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:62:1:62:1 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:62:1:62:13 | call to singleton_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:63:1:63:1 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:63:1:63:12 | call to instance_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:65:1:69:3 | D | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:65:11:65:11 | C | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:60:1:60:1 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:60:1:60:9 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:60:5:60:5 | C | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:60:5:60:9 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:61:1:61:1 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:61:1:61:5 | call to baz | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:62:1:62:1 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:62:1:62:13 | call to singleton_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:63:1:63:1 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:63:1:63:12 | call to instance_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:65:1:69:3 | D | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:65:11:65:11 | C | calls.rb:1:1:550:40 | calls.rb | | calls.rb:66:5:68:7 | baz | calls.rb:65:1:69:3 | D | | calls.rb:67:9:67:13 | call to super | calls.rb:65:1:69:3 | D | -| calls.rb:71:1:71:1 | d | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:71:1:71:9 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:71:5:71:5 | D | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:71:5:71:9 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:72:1:72:1 | d | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:72:1:72:5 | call to baz | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:73:1:73:1 | d | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:73:1:73:13 | call to singleton_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:74:1:74:1 | d | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:74:1:74:12 | call to instance_m | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:76:1:79:3 | optional_arg | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:76:18:76:18 | a | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:76:18:76:18 | a | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:76:22:76:22 | 4 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:76:25:76:25 | b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:76:25:76:25 | b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:76:28:76:28 | 5 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:77:5:77:5 | a | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:77:5:77:16 | call to bit_length | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:78:5:78:5 | b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:78:5:78:16 | call to bit_length | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:81:1:83:3 | call_block | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:82:5:82:11 | yield ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:82:11:82:11 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:85:1:89:3 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:86:5:86:7 | var | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:86:5:86:18 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:86:11:86:14 | Hash | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:86:11:86:18 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:87:5:87:7 | var | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:87:5:87:10 | ...[...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:87:9:87:9 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:5:88:29 | call to call_block | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:5:88:29 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:16:88:29 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:19:88:19 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:19:88:19 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:22:88:24 | var | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:22:88:27 | ...[...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:88:26:88:26 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:91:1:94:3 | Integer | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:71:1:71:1 | d | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:71:1:71:9 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:71:5:71:5 | D | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:71:5:71:9 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:72:1:72:1 | d | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:72:1:72:5 | call to baz | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:73:1:73:1 | d | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:73:1:73:13 | call to singleton_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:74:1:74:1 | d | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:74:1:74:12 | call to instance_m | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:76:1:79:3 | optional_arg | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:76:18:76:18 | a | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:76:18:76:18 | a | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:76:22:76:22 | 4 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:76:25:76:25 | b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:76:25:76:25 | b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:76:28:76:28 | 5 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:77:5:77:5 | a | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:77:5:77:16 | call to bit_length | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:78:5:78:5 | b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:78:5:78:16 | call to bit_length | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:81:1:83:3 | call_block | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:82:5:82:11 | yield ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:82:11:82:11 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:85:1:89:3 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:86:5:86:7 | var | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:86:5:86:18 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:86:11:86:14 | Hash | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:86:11:86:18 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:87:5:87:7 | var | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:87:5:87:10 | ...[...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:87:9:87:9 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:5:88:29 | call to call_block | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:5:88:29 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:16:88:29 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:19:88:19 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:19:88:19 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:22:88:24 | var | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:22:88:27 | ...[...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:88:26:88:26 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:91:1:94:3 | Integer | calls.rb:1:1:550:40 | calls.rb | | calls.rb:92:5:92:23 | bit_length | calls.rb:91:1:94:3 | Integer | | calls.rb:93:5:93:16 | abs | calls.rb:91:1:94:3 | Integer | -| calls.rb:96:1:98:3 | String | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:96:1:98:3 | String | calls.rb:1:1:550:40 | calls.rb | | calls.rb:97:5:97:23 | capitalize | calls.rb:96:1:98:3 | String | -| calls.rb:100:1:103:3 | Kernel | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:100:1:103:3 | Kernel | calls.rb:1:1:550:40 | calls.rb | | calls.rb:101:5:101:25 | alias ... | calls.rb:100:1:103:3 | Kernel | | calls.rb:101:11:101:19 | :old_puts | calls.rb:100:1:103:3 | Kernel | | calls.rb:101:11:101:19 | old_puts | calls.rb:100:1:103:3 | Kernel | @@ -551,7 +555,7 @@ enclosingModule | calls.rb:102:17:102:26 | call to old_puts | calls.rb:100:1:103:3 | Kernel | | calls.rb:102:17:102:26 | self | calls.rb:100:1:103:3 | Kernel | | calls.rb:102:26:102:26 | x | calls.rb:100:1:103:3 | Kernel | -| calls.rb:105:1:113:3 | Module | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:105:1:113:3 | Module | calls.rb:1:1:550:40 | calls.rb | | calls.rb:106:5:106:31 | alias ... | calls.rb:105:1:113:3 | Module | | calls.rb:106:11:106:22 | :old_include | calls.rb:105:1:113:3 | Module | | calls.rb:106:11:106:22 | old_include | calls.rb:105:1:113:3 | Module | @@ -566,13 +570,13 @@ enclosingModule | calls.rb:109:21:109:21 | x | calls.rb:105:1:113:3 | Module | | calls.rb:111:5:111:20 | prepend | calls.rb:105:1:113:3 | Module | | calls.rb:112:5:112:20 | private | calls.rb:105:1:113:3 | Module | -| calls.rb:115:1:118:3 | Object | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:115:16:115:21 | Module | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:115:1:118:3 | Object | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:115:16:115:21 | Module | calls.rb:1:1:550:40 | calls.rb | | calls.rb:116:5:116:18 | call to include | calls.rb:115:1:118:3 | Object | | calls.rb:116:5:116:18 | self | calls.rb:115:1:118:3 | Object | | calls.rb:116:13:116:18 | Kernel | calls.rb:115:1:118:3 | Object | | calls.rb:117:5:117:16 | new | calls.rb:115:1:118:3 | Object | -| calls.rb:120:1:123:3 | Hash | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:120:1:123:3 | Hash | calls.rb:1:1:550:40 | calls.rb | | calls.rb:121:5:121:25 | alias ... | calls.rb:120:1:123:3 | Hash | | calls.rb:121:11:121:21 | :old_lookup | calls.rb:120:1:123:3 | Hash | | calls.rb:121:11:121:21 | old_lookup | calls.rb:120:1:123:3 | Hash | @@ -584,7 +588,7 @@ enclosingModule | calls.rb:122:15:122:27 | call to old_lookup | calls.rb:120:1:123:3 | Hash | | calls.rb:122:15:122:27 | self | calls.rb:120:1:123:3 | Hash | | calls.rb:122:26:122:26 | x | calls.rb:120:1:123:3 | Hash | -| calls.rb:125:1:138:3 | Array | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:125:1:138:3 | Array | calls.rb:1:1:550:40 | calls.rb | | calls.rb:126:3:126:23 | alias ... | calls.rb:125:1:138:3 | Array | | calls.rb:126:9:126:19 | :old_lookup | calls.rb:125:1:138:3 | Array | | calls.rb:126:9:126:19 | old_lookup | calls.rb:125:1:138:3 | Array | @@ -620,130 +624,130 @@ enclosingModule | calls.rb:135:9:135:14 | ... = ... | calls.rb:125:1:138:3 | Array | | calls.rb:135:11:135:12 | ... + ... | calls.rb:125:1:138:3 | Array | | calls.rb:135:14:135:14 | 1 | calls.rb:125:1:138:3 | Array | -| calls.rb:140:1:142:3 | funny | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:141:5:141:20 | yield ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:141:11:141:20 | "prefix: " | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:141:12:141:19 | prefix: | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:1:144:30 | call to funny | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:1:144:30 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:7:144:30 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:10:144:10 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:10:144:10 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:13:144:29 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:13:144:29 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:18:144:18 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:144:18:144:29 | call to capitalize | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:146:1:146:3 | "a" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:146:1:146:14 | call to capitalize | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:146:2:146:2 | a | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:147:1:147:1 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:147:1:147:12 | call to bit_length | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:148:1:148:1 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:148:1:148:5 | call to abs | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:1:150:13 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:1:150:13 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:1:150:13 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:1:150:62 | call to foreach | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:2:150:4 | "a" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:3:150:3 | a | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:6:150:8 | "b" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:7:150:7 | b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:10:150:12 | "c" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:11:150:11 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:23:150:62 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:26:150:26 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:26:150:26 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:29:150:29 | v | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:29:150:29 | v | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:32:150:61 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:32:150:61 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:37:150:61 | "#{...} -> #{...}" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:38:150:41 | #{...} | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:40:150:40 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:42:150:45 | -> | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:46:150:60 | #{...} | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:48:150:48 | v | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:150:48:150:59 | call to capitalize | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:1:152:7 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:1:152:7 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:1:152:7 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:1:152:35 | call to foreach | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:2:152:2 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:4:152:4 | 2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:6:152:6 | 3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:17:152:35 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:20:152:20 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:20:152:20 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:23:152:23 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:152:23:152:34 | call to bit_length | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:1:154:7 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:1:154:7 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:1:154:7 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:1:154:40 | call to foreach | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:2:154:2 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:4:154:4 | 2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:6:154:6 | 3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:17:154:40 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:20:154:20 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:20:154:20 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:23:154:39 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:23:154:39 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:28:154:28 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:154:28:154:39 | call to capitalize | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:1:156:8 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:1:156:8 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:1:156:8 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:1:156:37 | call to foreach | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:2:156:2 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:4:156:5 | - ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:5:156:5 | 2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:7:156:7 | 3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:18:156:37 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:21:156:21 | _ | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:21:156:21 | _ | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:24:156:24 | v | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:24:156:24 | v | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:27:156:36 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:27:156:36 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:32:156:32 | v | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:156:32:156:36 | call to abs | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:158:1:160:3 | indirect | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:158:14:158:15 | &b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:158:15:158:15 | b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:159:5:159:17 | call to call_block | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:159:5:159:17 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:159:16:159:17 | &... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:159:17:159:17 | b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:162:1:162:28 | call to indirect | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:162:1:162:28 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:162:10:162:28 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:162:13:162:13 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:162:13:162:13 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:162:16:162:16 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:162:16:162:27 | call to bit_length | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:165:1:169:3 | S | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:140:1:142:3 | funny | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:141:5:141:20 | yield ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:141:11:141:20 | "prefix: " | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:141:12:141:19 | prefix: | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:1:144:30 | call to funny | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:1:144:30 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:7:144:30 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:10:144:10 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:10:144:10 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:13:144:29 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:13:144:29 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:18:144:18 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:144:18:144:29 | call to capitalize | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:146:1:146:3 | "a" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:146:1:146:14 | call to capitalize | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:146:2:146:2 | a | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:147:1:147:1 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:147:1:147:12 | call to bit_length | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:148:1:148:1 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:148:1:148:5 | call to abs | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:1:150:13 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:1:150:13 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:1:150:13 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:1:150:62 | call to foreach | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:2:150:4 | "a" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:3:150:3 | a | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:6:150:8 | "b" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:7:150:7 | b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:10:150:12 | "c" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:11:150:11 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:23:150:62 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:26:150:26 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:26:150:26 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:29:150:29 | v | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:29:150:29 | v | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:32:150:61 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:32:150:61 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:37:150:61 | "#{...} -> #{...}" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:38:150:41 | #{...} | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:40:150:40 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:42:150:45 | -> | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:46:150:60 | #{...} | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:48:150:48 | v | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:150:48:150:59 | call to capitalize | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:1:152:7 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:1:152:7 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:1:152:7 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:1:152:35 | call to foreach | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:2:152:2 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:4:152:4 | 2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:6:152:6 | 3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:17:152:35 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:20:152:20 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:20:152:20 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:23:152:23 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:152:23:152:34 | call to bit_length | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:1:154:7 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:1:154:7 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:1:154:7 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:1:154:40 | call to foreach | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:2:154:2 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:4:154:4 | 2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:6:154:6 | 3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:17:154:40 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:20:154:20 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:20:154:20 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:23:154:39 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:23:154:39 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:28:154:28 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:154:28:154:39 | call to capitalize | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:1:156:8 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:1:156:8 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:1:156:8 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:1:156:37 | call to foreach | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:2:156:2 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:4:156:5 | - ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:5:156:5 | 2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:7:156:7 | 3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:18:156:37 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:21:156:21 | _ | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:21:156:21 | _ | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:24:156:24 | v | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:24:156:24 | v | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:27:156:36 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:27:156:36 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:32:156:32 | v | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:156:32:156:36 | call to abs | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:158:1:160:3 | indirect | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:158:14:158:15 | &b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:158:15:158:15 | b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:159:5:159:17 | call to call_block | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:159:5:159:17 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:159:16:159:17 | &... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:159:17:159:17 | b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:162:1:162:28 | call to indirect | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:162:1:162:28 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:162:10:162:28 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:162:13:162:13 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:162:13:162:13 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:162:16:162:16 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:162:16:162:27 | call to bit_length | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:165:1:169:3 | S | calls.rb:1:1:550:40 | calls.rb | | calls.rb:166:5:168:7 | s_method | calls.rb:165:1:169:3 | S | | calls.rb:167:9:167:12 | self | calls.rb:165:1:169:3 | S | | calls.rb:167:9:167:17 | call to to_s | calls.rb:165:1:169:3 | S | -| calls.rb:171:1:174:3 | A | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:171:11:171:11 | S | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:171:1:174:3 | A | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:171:11:171:11 | S | calls.rb:1:1:550:40 | calls.rb | | calls.rb:172:5:173:7 | to_s | calls.rb:171:1:174:3 | A | -| calls.rb:176:1:179:3 | B | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:176:11:176:11 | S | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:176:1:179:3 | B | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:176:11:176:11 | S | calls.rb:1:1:550:40 | calls.rb | | calls.rb:177:5:178:7 | to_s | calls.rb:176:1:179:3 | B | -| calls.rb:181:1:181:1 | S | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:181:1:181:5 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:181:1:181:14 | call to s_method | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:182:1:182:1 | A | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:182:1:182:5 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:182:1:182:14 | call to s_method | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:183:1:183:1 | B | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:183:1:183:5 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:183:1:183:14 | call to s_method | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:185:1:186:3 | private_on_main | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:188:1:188:15 | call to private_on_main | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:188:1:188:15 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:190:1:226:3 | Singletons | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:181:1:181:1 | S | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:181:1:181:5 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:181:1:181:14 | call to s_method | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:182:1:182:1 | A | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:182:1:182:5 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:182:1:182:14 | call to s_method | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:183:1:183:1 | B | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:183:1:183:5 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:183:1:183:14 | call to s_method | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:185:1:186:3 | private_on_main | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:188:1:188:15 | call to private_on_main | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:188:1:188:15 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:190:1:226:3 | Singletons | calls.rb:1:1:550:40 | calls.rb | | calls.rb:191:5:194:7 | singleton_a | calls.rb:190:1:226:3 | Singletons | | calls.rb:191:9:191:12 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:192:9:192:26 | call to puts | calls.rb:190:1:226:3 | Singletons | @@ -793,126 +797,126 @@ enclosingModule | calls.rb:223:5:225:7 | call_singleton_g | calls.rb:190:1:226:3 | Singletons | | calls.rb:224:9:224:12 | self | calls.rb:190:1:226:3 | Singletons | | calls.rb:224:9:224:24 | call to singleton_g | calls.rb:190:1:226:3 | Singletons | -| calls.rb:228:1:228:10 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:228:1:228:22 | call to singleton_a | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:229:1:229:10 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:229:1:229:22 | call to singleton_f | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:231:1:231:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:231:1:231:19 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:231:6:231:15 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:231:6:231:19 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:233:1:233:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:233:1:233:11 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:234:1:234:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:234:1:234:14 | call to singleton_e | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:236:1:238:3 | singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:236:5:236:6 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:237:5:237:24 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:237:5:237:24 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:237:10:237:24 | "singleton_g_1" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:237:11:237:23 | singleton_g_1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:240:1:240:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:240:1:240:14 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:241:1:241:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:241:1:241:19 | call to call_singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:243:1:245:3 | singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:243:5:243:6 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:244:5:244:24 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:244:5:244:24 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:244:10:244:24 | "singleton_g_2" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:244:11:244:23 | singleton_g_2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:247:1:247:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:247:1:247:14 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:248:1:248:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:248:1:248:19 | call to call_singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:250:1:254:3 | class << ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:250:10:250:11 | c1 | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:228:1:228:10 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:228:1:228:22 | call to singleton_a | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:229:1:229:10 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:229:1:229:22 | call to singleton_f | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:231:1:231:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:231:1:231:19 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:231:6:231:15 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:231:6:231:19 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:233:1:233:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:233:1:233:11 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:234:1:234:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:234:1:234:14 | call to singleton_e | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:236:1:238:3 | singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:236:5:236:6 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:237:5:237:24 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:237:5:237:24 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:237:10:237:24 | "singleton_g_1" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:237:11:237:23 | singleton_g_1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:240:1:240:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:240:1:240:14 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:241:1:241:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:241:1:241:19 | call to call_singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:243:1:245:3 | singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:243:5:243:6 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:244:5:244:24 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:244:5:244:24 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:244:10:244:24 | "singleton_g_2" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:244:11:244:23 | singleton_g_2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:247:1:247:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:247:1:247:14 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:248:1:248:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:248:1:248:19 | call to call_singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:250:1:254:3 | class << ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:250:10:250:11 | c1 | calls.rb:1:1:550:40 | calls.rb | | calls.rb:251:5:253:7 | singleton_g | calls.rb:250:1:254:3 | class << ... | | calls.rb:252:9:252:28 | call to puts | calls.rb:250:1:254:3 | class << ... | | calls.rb:252:9:252:28 | self | calls.rb:250:1:254:3 | class << ... | | calls.rb:252:14:252:28 | "singleton_g_3" | calls.rb:250:1:254:3 | class << ... | | calls.rb:252:15:252:27 | singleton_g_3 | calls.rb:250:1:254:3 | class << ... | -| calls.rb:256:1:256:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:256:1:256:14 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:257:1:257:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:257:1:257:19 | call to call_singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:259:1:259:2 | c2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:259:1:259:19 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:259:6:259:15 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:259:6:259:19 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:260:1:260:2 | c2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:260:1:260:14 | call to singleton_e | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:261:1:261:2 | c2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:261:1:261:14 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:263:1:263:4 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:263:1:263:8 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:265:1:265:16 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:265:1:265:16 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:265:6:265:16 | "top-level" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:265:7:265:15 | top-level | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:267:1:269:3 | singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:267:5:267:14 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:268:5:268:22 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:268:5:268:22 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:268:10:268:22 | "singleton_g" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:268:11:268:21 | singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:271:1:271:10 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:271:1:271:22 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:272:1:272:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:272:1:272:14 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:273:1:273:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:273:1:273:19 | call to call_singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:274:1:274:2 | c2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:274:1:274:14 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:275:1:275:2 | c3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:275:1:275:19 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:275:6:275:15 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:275:6:275:19 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:276:1:276:2 | c3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:276:1:276:14 | call to singleton_g | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:278:1:286:3 | create | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:278:12:278:15 | type | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:278:12:278:15 | type | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:279:5:279:8 | type | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:279:5:279:12 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:279:5:279:21 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:281:5:283:7 | singleton_h | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:281:9:281:12 | type | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:282:9:282:26 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:282:9:282:26 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:282:14:282:26 | "singleton_h" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:282:15:282:25 | singleton_h | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:285:5:285:8 | type | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:285:5:285:20 | call to singleton_h | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:288:1:288:17 | call to create | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:288:1:288:17 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:288:8:288:17 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:289:1:289:10 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:289:1:289:22 | call to singleton_h | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:291:1:291:1 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:291:1:291:14 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:291:5:291:14 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:293:1:297:3 | class << ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:293:10:293:10 | x | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:256:1:256:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:256:1:256:14 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:257:1:257:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:257:1:257:19 | call to call_singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:259:1:259:2 | c2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:259:1:259:19 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:259:6:259:15 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:259:6:259:19 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:260:1:260:2 | c2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:260:1:260:14 | call to singleton_e | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:261:1:261:2 | c2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:261:1:261:14 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:263:1:263:4 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:263:1:263:8 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:265:1:265:16 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:265:1:265:16 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:265:6:265:16 | "top-level" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:265:7:265:15 | top-level | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:267:1:269:3 | singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:267:5:267:14 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:268:5:268:22 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:268:5:268:22 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:268:10:268:22 | "singleton_g" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:268:11:268:21 | singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:271:1:271:10 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:271:1:271:22 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:272:1:272:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:272:1:272:14 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:273:1:273:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:273:1:273:19 | call to call_singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:274:1:274:2 | c2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:274:1:274:14 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:275:1:275:2 | c3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:275:1:275:19 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:275:6:275:15 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:275:6:275:19 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:276:1:276:2 | c3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:276:1:276:14 | call to singleton_g | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:278:1:286:3 | create | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:278:12:278:15 | type | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:278:12:278:15 | type | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:279:5:279:8 | type | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:279:5:279:12 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:279:5:279:21 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:281:5:283:7 | singleton_h | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:281:9:281:12 | type | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:282:9:282:26 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:282:9:282:26 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:282:14:282:26 | "singleton_h" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:282:15:282:25 | singleton_h | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:285:5:285:8 | type | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:285:5:285:20 | call to singleton_h | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:288:1:288:17 | call to create | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:288:1:288:17 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:288:8:288:17 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:289:1:289:10 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:289:1:289:22 | call to singleton_h | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:291:1:291:1 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:291:1:291:14 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:291:5:291:14 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:293:1:297:3 | class << ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:293:10:293:10 | x | calls.rb:1:1:550:40 | calls.rb | | calls.rb:294:5:296:7 | singleton_i | calls.rb:293:1:297:3 | class << ... | | calls.rb:295:9:295:26 | call to puts | calls.rb:293:1:297:3 | class << ... | | calls.rb:295:9:295:26 | self | calls.rb:293:1:297:3 | class << ... | | calls.rb:295:14:295:26 | "singleton_i" | calls.rb:293:1:297:3 | class << ... | | calls.rb:295:15:295:25 | singleton_i | calls.rb:293:1:297:3 | class << ... | -| calls.rb:299:1:299:1 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:299:1:299:13 | call to singleton_i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:300:1:300:10 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:300:1:300:22 | call to singleton_i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:302:1:306:3 | class << ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:302:10:302:19 | Singletons | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:299:1:299:1 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:299:1:299:13 | call to singleton_i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:300:1:300:10 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:300:1:300:22 | call to singleton_i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:302:1:306:3 | class << ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:302:10:302:19 | Singletons | calls.rb:1:1:550:40 | calls.rb | | calls.rb:303:5:305:7 | singleton_j | calls.rb:302:1:306:3 | class << ... | | calls.rb:304:9:304:26 | call to puts | calls.rb:302:1:306:3 | class << ... | | calls.rb:304:9:304:26 | self | calls.rb:302:1:306:3 | class << ... | | calls.rb:304:14:304:26 | "singleton_j" | calls.rb:302:1:306:3 | class << ... | | calls.rb:304:15:304:25 | singleton_j | calls.rb:302:1:306:3 | class << ... | -| calls.rb:308:1:308:10 | Singletons | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:308:1:308:22 | call to singleton_j | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:310:1:321:3 | SelfNew | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:308:1:308:10 | Singletons | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:308:1:308:22 | call to singleton_j | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:310:1:321:3 | SelfNew | calls.rb:1:1:550:40 | calls.rb | | calls.rb:311:5:314:7 | instance | calls.rb:310:1:321:3 | SelfNew | | calls.rb:312:9:312:31 | call to puts | calls.rb:310:1:321:3 | SelfNew | | calls.rb:312:9:312:31 | self | calls.rb:310:1:321:3 | SelfNew | @@ -929,110 +933,110 @@ enclosingModule | calls.rb:320:5:320:7 | call to new | calls.rb:310:1:321:3 | SelfNew | | calls.rb:320:5:320:7 | self | calls.rb:310:1:321:3 | SelfNew | | calls.rb:320:5:320:16 | call to instance | calls.rb:310:1:321:3 | SelfNew | -| calls.rb:323:1:323:7 | SelfNew | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:323:1:323:17 | call to singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:325:1:329:3 | C1 | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:323:1:323:7 | SelfNew | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:323:1:323:17 | call to singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:325:1:329:3 | C1 | calls.rb:1:1:550:40 | calls.rb | | calls.rb:326:5:328:7 | instance | calls.rb:325:1:329:3 | C1 | | calls.rb:327:9:327:26 | call to puts | calls.rb:325:1:329:3 | C1 | | calls.rb:327:9:327:26 | self | calls.rb:325:1:329:3 | C1 | | calls.rb:327:14:327:26 | "C1#instance" | calls.rb:325:1:329:3 | C1 | | calls.rb:327:15:327:25 | C1#instance | calls.rb:325:1:329:3 | C1 | -| calls.rb:331:1:335:3 | C2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:331:12:331:13 | C1 | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:331:1:335:3 | C2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:331:12:331:13 | C1 | calls.rb:1:1:550:40 | calls.rb | | calls.rb:332:5:334:7 | instance | calls.rb:331:1:335:3 | C2 | | calls.rb:333:9:333:26 | call to puts | calls.rb:331:1:335:3 | C2 | | calls.rb:333:9:333:26 | self | calls.rb:331:1:335:3 | C2 | | calls.rb:333:14:333:26 | "C2#instance" | calls.rb:331:1:335:3 | C2 | | calls.rb:333:15:333:25 | C2#instance | calls.rb:331:1:335:3 | C2 | -| calls.rb:337:1:341:3 | C3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:337:12:337:13 | C2 | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:337:1:341:3 | C3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:337:12:337:13 | C2 | calls.rb:1:1:550:40 | calls.rb | | calls.rb:338:5:340:7 | instance | calls.rb:337:1:341:3 | C3 | | calls.rb:339:9:339:26 | call to puts | calls.rb:337:1:341:3 | C3 | | calls.rb:339:9:339:26 | self | calls.rb:337:1:341:3 | C3 | | calls.rb:339:14:339:26 | "C3#instance" | calls.rb:337:1:341:3 | C3 | | calls.rb:339:15:339:25 | C3#instance | calls.rb:337:1:341:3 | C3 | -| calls.rb:343:1:359:3 | pattern_dispatch | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:343:22:343:22 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:343:22:343:22 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:344:5:352:7 | case ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:344:10:344:10 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:345:5:346:18 | when ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:345:10:345:11 | C3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:345:12:346:18 | then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:346:9:346:9 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:346:9:346:18 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:347:5:348:18 | when ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:347:10:347:11 | C2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:347:12:348:18 | then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:348:9:348:9 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:348:9:348:18 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:349:5:350:18 | when ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:349:10:349:11 | C1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:349:12:350:18 | then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:350:9:350:9 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:350:9:350:18 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:351:5:351:8 | else ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:354:5:358:7 | case ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:354:10:354:10 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:355:9:355:29 | in ... then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:355:12:355:13 | C3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:355:15:355:29 | then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:355:20:355:20 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:355:20:355:29 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:356:9:356:36 | in ... then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:356:12:356:13 | C2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:356:12:356:19 | ... => ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:356:18:356:19 | c2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:356:21:356:36 | then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:356:26:356:27 | c2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:356:26:356:36 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:357:9:357:36 | in ... then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:357:12:357:13 | C1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:357:12:357:19 | ... => ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:357:18:357:19 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:357:21:357:36 | then ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:357:26:357:27 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:357:26:357:36 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:361:1:361:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:361:1:361:11 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:361:6:361:7 | C1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:361:6:361:11 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:362:1:362:2 | c1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:362:1:362:11 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:363:1:363:25 | call to pattern_dispatch | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:363:1:363:25 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:363:18:363:25 | ( ... ) | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:363:19:363:20 | C1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:363:19:363:24 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:364:1:364:25 | call to pattern_dispatch | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:364:1:364:25 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:364:18:364:25 | ( ... ) | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:364:19:364:20 | C2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:364:19:364:24 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:365:1:365:25 | call to pattern_dispatch | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:365:1:365:25 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:365:18:365:25 | ( ... ) | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:365:19:365:20 | C3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:365:19:365:24 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:367:1:371:3 | add_singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:367:19:367:19 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:367:19:367:19 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:368:5:370:7 | instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:368:9:368:9 | x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:369:9:369:28 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:369:9:369:28 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:369:14:369:28 | "instance_on x" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:369:15:369:27 | instance_on x | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:373:1:373:2 | c3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:373:1:373:11 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:373:6:373:7 | C1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:373:6:373:11 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:374:1:374:16 | call to add_singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:374:1:374:16 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:374:15:374:16 | c3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:375:1:375:2 | c3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:375:1:375:11 | call to instance | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:377:1:397:3 | SingletonOverride1 | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:343:1:359:3 | pattern_dispatch | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:343:22:343:22 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:343:22:343:22 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:344:5:352:7 | case ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:344:10:344:10 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:345:5:346:18 | when ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:345:10:345:11 | C3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:345:12:346:18 | then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:346:9:346:9 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:346:9:346:18 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:347:5:348:18 | when ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:347:10:347:11 | C2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:347:12:348:18 | then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:348:9:348:9 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:348:9:348:18 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:349:5:350:18 | when ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:349:10:349:11 | C1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:349:12:350:18 | then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:350:9:350:9 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:350:9:350:18 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:351:5:351:8 | else ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:354:5:358:7 | case ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:354:10:354:10 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:355:9:355:29 | in ... then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:355:12:355:13 | C3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:355:15:355:29 | then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:355:20:355:20 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:355:20:355:29 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:356:9:356:36 | in ... then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:356:12:356:13 | C2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:356:12:356:19 | ... => ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:356:18:356:19 | c2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:356:21:356:36 | then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:356:26:356:27 | c2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:356:26:356:36 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:357:9:357:36 | in ... then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:357:12:357:13 | C1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:357:12:357:19 | ... => ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:357:18:357:19 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:357:21:357:36 | then ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:357:26:357:27 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:357:26:357:36 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:361:1:361:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:361:1:361:11 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:361:6:361:7 | C1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:361:6:361:11 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:362:1:362:2 | c1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:362:1:362:11 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:363:1:363:25 | call to pattern_dispatch | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:363:1:363:25 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:363:18:363:25 | ( ... ) | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:363:19:363:20 | C1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:363:19:363:24 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:364:1:364:25 | call to pattern_dispatch | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:364:1:364:25 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:364:18:364:25 | ( ... ) | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:364:19:364:20 | C2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:364:19:364:24 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:365:1:365:25 | call to pattern_dispatch | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:365:1:365:25 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:365:18:365:25 | ( ... ) | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:365:19:365:20 | C3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:365:19:365:24 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:367:1:371:3 | add_singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:367:19:367:19 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:367:19:367:19 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:368:5:370:7 | instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:368:9:368:9 | x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:369:9:369:28 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:369:9:369:28 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:369:14:369:28 | "instance_on x" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:369:15:369:27 | instance_on x | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:373:1:373:2 | c3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:373:1:373:11 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:373:6:373:7 | C1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:373:6:373:11 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:374:1:374:16 | call to add_singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:374:1:374:16 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:374:15:374:16 | c3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:375:1:375:2 | c3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:375:1:375:11 | call to instance | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:377:1:397:3 | SingletonOverride1 | calls.rb:1:1:550:40 | calls.rb | | calls.rb:378:5:386:7 | class << ... | calls.rb:377:1:397:3 | SingletonOverride1 | | calls.rb:378:14:378:17 | self | calls.rb:377:1:397:3 | SingletonOverride1 | | calls.rb:379:9:381:11 | singleton1 | calls.rb:378:5:386:7 | class << ... | @@ -1055,274 +1059,282 @@ enclosingModule | calls.rb:393:9:393:18 | self | calls.rb:377:1:397:3 | SingletonOverride1 | | calls.rb:396:5:396:14 | call to singleton2 | calls.rb:377:1:397:3 | SingletonOverride1 | | calls.rb:396:5:396:14 | self | calls.rb:377:1:397:3 | SingletonOverride1 | -| calls.rb:399:1:399:18 | SingletonOverride1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:399:1:399:34 | call to call_singleton1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:400:1:400:18 | SingletonOverride1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:400:1:400:34 | call to call_singleton2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:402:1:412:3 | SingletonOverride2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:402:28:402:45 | SingletonOverride1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:403:5:407:7 | class << ... | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:403:14:403:17 | self | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:404:9:406:11 | singleton1 | calls.rb:403:5:407:7 | class << ... | -| calls.rb:405:13:405:48 | call to puts | calls.rb:403:5:407:7 | class << ... | -| calls.rb:405:13:405:48 | self | calls.rb:403:5:407:7 | class << ... | -| calls.rb:405:18:405:48 | "SingletonOverride2#singleton1" | calls.rb:403:5:407:7 | class << ... | -| calls.rb:405:19:405:47 | SingletonOverride2#singleton1 | calls.rb:403:5:407:7 | class << ... | -| calls.rb:409:5:411:7 | singleton2 | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:409:9:409:12 | self | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:410:9:410:44 | call to puts | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:410:9:410:44 | self | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:410:14:410:44 | "SingletonOverride2#singleton2" | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:410:15:410:43 | SingletonOverride2#singleton2 | calls.rb:402:1:412:3 | SingletonOverride2 | -| calls.rb:414:1:414:18 | SingletonOverride2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:414:1:414:34 | call to call_singleton1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:415:1:415:18 | SingletonOverride2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:415:1:415:34 | call to call_singleton2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:417:1:445:3 | ConditionalInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:418:5:422:7 | if ... | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:418:8:418:13 | call to rand | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:418:8:418:13 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:418:8:418:17 | ... > ... | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:418:17:418:17 | 0 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:418:19:421:11 | then ... | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:419:9:421:11 | m1 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:420:13:420:48 | call to puts | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:420:13:420:48 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:420:18:420:48 | "ConditionalInstanceMethods#m1" | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:420:19:420:47 | ConditionalInstanceMethods#m1 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:424:5:436:7 | m2 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:425:9:425:44 | call to puts | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:425:9:425:44 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:425:14:425:44 | "ConditionalInstanceMethods#m2" | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:425:15:425:43 | ConditionalInstanceMethods#m2 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:427:9:433:11 | m3 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:428:13:428:48 | call to puts | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:428:13:428:48 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:428:18:428:48 | "ConditionalInstanceMethods#m3" | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:428:19:428:47 | ConditionalInstanceMethods#m3 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:430:13:432:15 | m4 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:431:17:431:52 | call to puts | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:431:17:431:52 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:431:22:431:52 | "ConditionalInstanceMethods#m4" | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:431:23:431:51 | ConditionalInstanceMethods#m4 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:435:9:435:10 | call to m3 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:435:9:435:10 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:438:5:444:7 | if ... | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:438:8:438:13 | call to rand | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:438:8:438:13 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:438:8:438:17 | ... > ... | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:438:17:438:17 | 0 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:438:19:443:18 | then ... | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:439:9:439:13 | Class | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:439:9:443:11 | call to new | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:439:9:443:15 | call to new | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:439:9:443:18 | call to m5 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:439:19:443:11 | do ... end | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:440:13:442:15 | m5 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:441:17:441:40 | call to puts | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:441:17:441:40 | self | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:441:22:441:40 | "AnonymousClass#m5" | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:441:23:441:39 | AnonymousClass#m5 | calls.rb:417:1:445:3 | ConditionalInstanceMethods | -| calls.rb:447:1:447:26 | ConditionalInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:447:1:447:30 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:447:1:447:33 | call to m1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:448:1:448:26 | ConditionalInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:448:1:448:30 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:448:1:448:33 | call to m3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:449:1:449:26 | ConditionalInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:449:1:449:30 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:449:1:449:33 | call to m2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:450:1:450:26 | ConditionalInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:450:1:450:30 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:450:1:450:33 | call to m3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:451:1:451:26 | ConditionalInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:451:1:451:30 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:451:1:451:33 | call to m4 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:452:1:452:26 | ConditionalInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:452:1:452:30 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:452:1:452:33 | call to m5 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:454:1:454:23 | EsotericInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:454:1:472:3 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:454:27:454:31 | Class | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:454:27:472:3 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:454:37:472:3 | do ... end | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:5:455:11 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:5:455:11 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:5:455:11 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:5:459:7 | call to each | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:6:455:6 | 0 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:8:455:8 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:10:455:10 | 2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:455:18:459:7 | do ... end | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:456:9:458:11 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:457:13:457:22 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:457:13:457:22 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:457:18:457:22 | "foo" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:457:19:457:21 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:461:5:461:9 | Class | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:461:5:465:7 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:461:5:465:11 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:461:5:465:15 | call to bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:461:15:465:7 | do ... end | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:462:9:464:11 | bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:463:13:463:22 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:463:13:463:22 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:463:18:463:22 | "bar" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:463:19:463:21 | bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:5:467:11 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:5:467:11 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:5:467:11 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:5:471:7 | call to each | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:6:467:6 | 0 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:8:467:8 | 1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:10:467:10 | 2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:18:471:7 | do ... end | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:22:467:22 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:467:22:467:22 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:468:9:470:11 | call to define_method | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:468:9:470:11 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:468:23:468:32 | "baz_#{...}" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:468:24:468:27 | baz_ | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:468:28:468:31 | #{...} | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:468:30:468:30 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:468:35:470:11 | do ... end | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:469:13:469:27 | call to puts | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:469:13:469:27 | self | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:469:18:469:27 | "baz_#{...}" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:469:19:469:22 | baz_ | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:469:23:469:26 | #{...} | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:469:25:469:25 | i | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:474:1:474:23 | EsotericInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:474:1:474:27 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:474:1:474:31 | call to foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:475:1:475:23 | EsotericInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:475:1:475:27 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:475:1:475:31 | call to bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:476:1:476:23 | EsotericInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:476:1:476:27 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:476:1:476:33 | call to baz_0 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:477:1:477:23 | EsotericInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:477:1:477:27 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:477:1:477:33 | call to baz_1 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:478:1:478:23 | EsotericInstanceMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:478:1:478:27 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:478:1:478:33 | call to baz_2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:480:1:486:3 | ExtendSingletonMethod | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:481:5:483:7 | singleton | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:482:9:482:46 | call to puts | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:482:9:482:46 | self | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:482:14:482:46 | "ExtendSingletonMethod#singleton" | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:482:15:482:45 | ExtendSingletonMethod#singleton | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:485:5:485:15 | call to extend | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:485:5:485:15 | self | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:485:12:485:15 | self | calls.rb:480:1:486:3 | ExtendSingletonMethod | -| calls.rb:488:1:488:21 | ExtendSingletonMethod | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:488:1:488:31 | call to singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:490:1:492:3 | ExtendSingletonMethod2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:491:5:491:32 | call to extend | calls.rb:490:1:492:3 | ExtendSingletonMethod2 | -| calls.rb:491:5:491:32 | self | calls.rb:490:1:492:3 | ExtendSingletonMethod2 | -| calls.rb:491:12:491:32 | ExtendSingletonMethod | calls.rb:490:1:492:3 | ExtendSingletonMethod2 | -| calls.rb:494:1:494:22 | ExtendSingletonMethod2 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:494:1:494:32 | call to singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:496:1:497:3 | ExtendSingletonMethod3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:499:1:499:22 | ExtendSingletonMethod3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:499:1:499:51 | call to extend | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:499:31:499:51 | ExtendSingletonMethod | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:501:1:501:22 | ExtendSingletonMethod3 | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:501:1:501:32 | call to singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:503:1:503:3 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:503:1:503:13 | ... = ... | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:503:7:503:13 | "hello" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:503:8:503:12 | hello | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:504:1:504:3 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:504:1:504:13 | call to singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:505:1:505:3 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:505:1:505:32 | call to extend | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:505:12:505:32 | ExtendSingletonMethod | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:507:1:507:3 | foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:507:1:507:13 | call to singleton | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:509:1:513:3 | ProtectedMethodInModule | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:510:5:512:7 | call to protected | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:510:5:512:7 | self | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:510:15:512:7 | foo | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:511:9:511:42 | call to puts | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:511:9:511:42 | self | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:511:14:511:42 | "ProtectedMethodInModule#foo" | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:511:15:511:41 | ProtectedMethodInModule#foo | calls.rb:509:1:513:3 | ProtectedMethodInModule | -| calls.rb:515:1:528:3 | ProtectedMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:516:5:516:35 | call to include | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:516:5:516:35 | self | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:516:13:516:35 | ProtectedMethodInModule | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:518:5:520:7 | call to protected | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:518:5:520:7 | self | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:518:15:520:7 | bar | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:519:9:519:35 | call to puts | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:519:9:519:35 | self | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:519:14:519:35 | "ProtectedMethods#bar" | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:519:15:519:34 | ProtectedMethods#bar | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:522:5:527:7 | baz | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:523:9:523:11 | call to foo | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:523:9:523:11 | self | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:524:9:524:11 | call to bar | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:524:9:524:11 | self | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:525:9:525:24 | ProtectedMethods | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:525:9:525:28 | call to new | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:525:9:525:32 | call to foo | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:526:9:526:24 | ProtectedMethods | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:526:9:526:28 | call to new | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:526:9:526:32 | call to bar | calls.rb:515:1:528:3 | ProtectedMethods | -| calls.rb:530:1:530:16 | ProtectedMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:530:1:530:20 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:530:1:530:24 | call to foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:531:1:531:16 | ProtectedMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:531:1:531:20 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:531:1:531:24 | call to bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:532:1:532:16 | ProtectedMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:532:1:532:20 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:532:1:532:24 | call to baz | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:534:1:539:3 | ProtectedMethodsSub | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:534:29:534:44 | ProtectedMethods | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:535:5:538:7 | baz | calls.rb:534:1:539:3 | ProtectedMethodsSub | -| calls.rb:536:9:536:11 | call to foo | calls.rb:534:1:539:3 | ProtectedMethodsSub | -| calls.rb:536:9:536:11 | self | calls.rb:534:1:539:3 | ProtectedMethodsSub | -| calls.rb:537:9:537:27 | ProtectedMethodsSub | calls.rb:534:1:539:3 | ProtectedMethodsSub | -| calls.rb:537:9:537:31 | call to new | calls.rb:534:1:539:3 | ProtectedMethodsSub | -| calls.rb:537:9:537:35 | call to foo | calls.rb:534:1:539:3 | ProtectedMethodsSub | -| calls.rb:541:1:541:19 | ProtectedMethodsSub | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:541:1:541:23 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:541:1:541:27 | call to foo | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:542:1:542:19 | ProtectedMethodsSub | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:542:1:542:23 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:542:1:542:27 | call to bar | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:543:1:543:19 | ProtectedMethodsSub | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:543:1:543:23 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:543:1:543:27 | call to baz | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:1:545:7 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:1:545:7 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:1:545:7 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:1:545:26 | call to each | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:2:545:2 | C | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:2:545:6 | call to new | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:14:545:26 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:17:545:17 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:17:545:17 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:20:545:20 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:545:20:545:24 | call to baz | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:1:546:13 | Array | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:1:546:13 | [...] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:1:546:13 | call to [] | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:1:546:39 | call to each | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:2:546:4 | "a" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:3:546:3 | a | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:6:546:8 | "b" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:7:546:7 | b | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:10:546:12 | "c" | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:11:546:11 | c | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:20:546:39 | { ... } | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:23:546:23 | s | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:23:546:23 | s | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:26:546:26 | s | calls.rb:1:1:546:40 | calls.rb | -| calls.rb:546:26:546:37 | call to capitalize | calls.rb:1:1:546:40 | calls.rb | +| calls.rb:399:1:399:18 | SingletonOverride1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:399:1:399:29 | call to singleton1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:400:1:400:18 | SingletonOverride1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:400:1:400:29 | call to singleton2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:401:1:401:18 | SingletonOverride1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:401:1:401:34 | call to call_singleton1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:402:1:402:18 | SingletonOverride1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:402:1:402:34 | call to call_singleton2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:404:1:414:3 | SingletonOverride2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:404:28:404:45 | SingletonOverride1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:405:5:409:7 | class << ... | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:405:14:405:17 | self | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:406:9:408:11 | singleton1 | calls.rb:405:5:409:7 | class << ... | +| calls.rb:407:13:407:48 | call to puts | calls.rb:405:5:409:7 | class << ... | +| calls.rb:407:13:407:48 | self | calls.rb:405:5:409:7 | class << ... | +| calls.rb:407:18:407:48 | "SingletonOverride2#singleton1" | calls.rb:405:5:409:7 | class << ... | +| calls.rb:407:19:407:47 | SingletonOverride2#singleton1 | calls.rb:405:5:409:7 | class << ... | +| calls.rb:411:5:413:7 | singleton2 | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:411:9:411:12 | self | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:412:9:412:44 | call to puts | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:412:9:412:44 | self | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:412:14:412:44 | "SingletonOverride2#singleton2" | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:412:15:412:43 | SingletonOverride2#singleton2 | calls.rb:404:1:414:3 | SingletonOverride2 | +| calls.rb:416:1:416:18 | SingletonOverride2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:416:1:416:29 | call to singleton1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:417:1:417:18 | SingletonOverride2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:417:1:417:29 | call to singleton2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:418:1:418:18 | SingletonOverride2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:418:1:418:34 | call to call_singleton1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:419:1:419:18 | SingletonOverride2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:419:1:419:34 | call to call_singleton2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:421:1:449:3 | ConditionalInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:422:5:426:7 | if ... | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:422:8:422:13 | call to rand | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:422:8:422:13 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:422:8:422:17 | ... > ... | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:422:17:422:17 | 0 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:422:19:425:11 | then ... | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:423:9:425:11 | m1 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:424:13:424:48 | call to puts | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:424:13:424:48 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:424:18:424:48 | "ConditionalInstanceMethods#m1" | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:424:19:424:47 | ConditionalInstanceMethods#m1 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:428:5:440:7 | m2 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:429:9:429:44 | call to puts | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:429:9:429:44 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:429:14:429:44 | "ConditionalInstanceMethods#m2" | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:429:15:429:43 | ConditionalInstanceMethods#m2 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:431:9:437:11 | m3 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:432:13:432:48 | call to puts | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:432:13:432:48 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:432:18:432:48 | "ConditionalInstanceMethods#m3" | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:432:19:432:47 | ConditionalInstanceMethods#m3 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:434:13:436:15 | m4 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:435:17:435:52 | call to puts | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:435:17:435:52 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:435:22:435:52 | "ConditionalInstanceMethods#m4" | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:435:23:435:51 | ConditionalInstanceMethods#m4 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:439:9:439:10 | call to m3 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:439:9:439:10 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:442:5:448:7 | if ... | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:442:8:442:13 | call to rand | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:442:8:442:13 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:442:8:442:17 | ... > ... | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:442:17:442:17 | 0 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:442:19:447:18 | then ... | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:443:9:443:13 | Class | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:443:9:447:11 | call to new | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:443:9:447:15 | call to new | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:443:9:447:18 | call to m5 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:443:19:447:11 | do ... end | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:444:13:446:15 | m5 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:445:17:445:40 | call to puts | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:445:17:445:40 | self | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:445:22:445:40 | "AnonymousClass#m5" | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:445:23:445:39 | AnonymousClass#m5 | calls.rb:421:1:449:3 | ConditionalInstanceMethods | +| calls.rb:451:1:451:26 | ConditionalInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:451:1:451:30 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:451:1:451:33 | call to m1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:452:1:452:26 | ConditionalInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:452:1:452:30 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:452:1:452:33 | call to m3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:453:1:453:26 | ConditionalInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:453:1:453:30 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:453:1:453:33 | call to m2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:454:1:454:26 | ConditionalInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:454:1:454:30 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:454:1:454:33 | call to m3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:455:1:455:26 | ConditionalInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:455:1:455:30 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:455:1:455:33 | call to m4 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:456:1:456:26 | ConditionalInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:456:1:456:30 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:456:1:456:33 | call to m5 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:458:1:458:23 | EsotericInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:458:1:476:3 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:458:27:458:31 | Class | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:458:27:476:3 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:458:37:476:3 | do ... end | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:5:459:11 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:5:459:11 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:5:459:11 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:5:463:7 | call to each | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:6:459:6 | 0 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:8:459:8 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:10:459:10 | 2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:459:18:463:7 | do ... end | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:460:9:462:11 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:461:13:461:22 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:461:13:461:22 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:461:18:461:22 | "foo" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:461:19:461:21 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:465:5:465:9 | Class | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:465:5:469:7 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:465:5:469:11 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:465:5:469:15 | call to bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:465:15:469:7 | do ... end | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:466:9:468:11 | bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:467:13:467:22 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:467:13:467:22 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:467:18:467:22 | "bar" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:467:19:467:21 | bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:5:471:11 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:5:471:11 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:5:471:11 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:5:475:7 | call to each | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:6:471:6 | 0 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:8:471:8 | 1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:10:471:10 | 2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:18:475:7 | do ... end | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:22:471:22 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:471:22:471:22 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:472:9:474:11 | call to define_method | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:472:9:474:11 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:472:23:472:32 | "baz_#{...}" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:472:24:472:27 | baz_ | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:472:28:472:31 | #{...} | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:472:30:472:30 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:472:35:474:11 | do ... end | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:473:13:473:27 | call to puts | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:473:13:473:27 | self | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:473:18:473:27 | "baz_#{...}" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:473:19:473:22 | baz_ | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:473:23:473:26 | #{...} | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:473:25:473:25 | i | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:478:1:478:23 | EsotericInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:478:1:478:27 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:478:1:478:31 | call to foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:479:1:479:23 | EsotericInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:479:1:479:27 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:479:1:479:31 | call to bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:480:1:480:23 | EsotericInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:480:1:480:27 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:480:1:480:33 | call to baz_0 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:481:1:481:23 | EsotericInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:481:1:481:27 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:481:1:481:33 | call to baz_1 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:482:1:482:23 | EsotericInstanceMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:482:1:482:27 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:482:1:482:33 | call to baz_2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:484:1:490:3 | ExtendSingletonMethod | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:485:5:487:7 | singleton | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:486:9:486:46 | call to puts | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:486:9:486:46 | self | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:486:14:486:46 | "ExtendSingletonMethod#singleton" | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:486:15:486:45 | ExtendSingletonMethod#singleton | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:489:5:489:15 | call to extend | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:489:5:489:15 | self | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:489:12:489:15 | self | calls.rb:484:1:490:3 | ExtendSingletonMethod | +| calls.rb:492:1:492:21 | ExtendSingletonMethod | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:492:1:492:31 | call to singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:494:1:496:3 | ExtendSingletonMethod2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:495:5:495:32 | call to extend | calls.rb:494:1:496:3 | ExtendSingletonMethod2 | +| calls.rb:495:5:495:32 | self | calls.rb:494:1:496:3 | ExtendSingletonMethod2 | +| calls.rb:495:12:495:32 | ExtendSingletonMethod | calls.rb:494:1:496:3 | ExtendSingletonMethod2 | +| calls.rb:498:1:498:22 | ExtendSingletonMethod2 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:498:1:498:32 | call to singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:500:1:501:3 | ExtendSingletonMethod3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:503:1:503:22 | ExtendSingletonMethod3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:503:1:503:51 | call to extend | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:503:31:503:51 | ExtendSingletonMethod | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:505:1:505:22 | ExtendSingletonMethod3 | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:505:1:505:32 | call to singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:507:1:507:3 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:507:1:507:13 | ... = ... | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:507:7:507:13 | "hello" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:507:8:507:12 | hello | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:508:1:508:3 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:508:1:508:13 | call to singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:509:1:509:3 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:509:1:509:32 | call to extend | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:509:12:509:32 | ExtendSingletonMethod | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:511:1:511:3 | foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:511:1:511:13 | call to singleton | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:513:1:517:3 | ProtectedMethodInModule | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:514:5:516:7 | call to protected | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:514:5:516:7 | self | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:514:15:516:7 | foo | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:515:9:515:42 | call to puts | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:515:9:515:42 | self | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:515:14:515:42 | "ProtectedMethodInModule#foo" | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:515:15:515:41 | ProtectedMethodInModule#foo | calls.rb:513:1:517:3 | ProtectedMethodInModule | +| calls.rb:519:1:532:3 | ProtectedMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:520:5:520:35 | call to include | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:520:5:520:35 | self | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:520:13:520:35 | ProtectedMethodInModule | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:522:5:524:7 | call to protected | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:522:5:524:7 | self | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:522:15:524:7 | bar | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:523:9:523:35 | call to puts | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:523:9:523:35 | self | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:523:14:523:35 | "ProtectedMethods#bar" | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:523:15:523:34 | ProtectedMethods#bar | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:526:5:531:7 | baz | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:527:9:527:11 | call to foo | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:527:9:527:11 | self | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:528:9:528:11 | call to bar | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:528:9:528:11 | self | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:529:9:529:24 | ProtectedMethods | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:529:9:529:28 | call to new | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:529:9:529:32 | call to foo | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:530:9:530:24 | ProtectedMethods | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:530:9:530:28 | call to new | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:530:9:530:32 | call to bar | calls.rb:519:1:532:3 | ProtectedMethods | +| calls.rb:534:1:534:16 | ProtectedMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:534:1:534:20 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:534:1:534:24 | call to foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:535:1:535:16 | ProtectedMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:535:1:535:20 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:535:1:535:24 | call to bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:536:1:536:16 | ProtectedMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:536:1:536:20 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:536:1:536:24 | call to baz | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:538:1:543:3 | ProtectedMethodsSub | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:538:29:538:44 | ProtectedMethods | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:539:5:542:7 | baz | calls.rb:538:1:543:3 | ProtectedMethodsSub | +| calls.rb:540:9:540:11 | call to foo | calls.rb:538:1:543:3 | ProtectedMethodsSub | +| calls.rb:540:9:540:11 | self | calls.rb:538:1:543:3 | ProtectedMethodsSub | +| calls.rb:541:9:541:27 | ProtectedMethodsSub | calls.rb:538:1:543:3 | ProtectedMethodsSub | +| calls.rb:541:9:541:31 | call to new | calls.rb:538:1:543:3 | ProtectedMethodsSub | +| calls.rb:541:9:541:35 | call to foo | calls.rb:538:1:543:3 | ProtectedMethodsSub | +| calls.rb:545:1:545:19 | ProtectedMethodsSub | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:545:1:545:23 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:545:1:545:27 | call to foo | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:546:1:546:19 | ProtectedMethodsSub | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:546:1:546:23 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:546:1:546:27 | call to bar | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:547:1:547:19 | ProtectedMethodsSub | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:547:1:547:23 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:547:1:547:27 | call to baz | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:1:549:7 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:1:549:7 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:1:549:7 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:1:549:26 | call to each | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:2:549:2 | C | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:2:549:6 | call to new | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:14:549:26 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:17:549:17 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:17:549:17 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:20:549:20 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:549:20:549:24 | call to baz | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:1:550:13 | Array | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:1:550:13 | [...] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:1:550:13 | call to [] | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:1:550:39 | call to each | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:2:550:4 | "a" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:3:550:3 | a | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:6:550:8 | "b" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:7:550:7 | b | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:10:550:12 | "c" | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:11:550:11 | c | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:20:550:39 | { ... } | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:23:550:23 | s | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:23:550:23 | s | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:26:550:26 | s | calls.rb:1:1:550:40 | calls.rb | +| calls.rb:550:26:550:37 | call to capitalize | calls.rb:1:1:550:40 | calls.rb | | hello.rb:1:1:8:3 | EnglishWords | hello.rb:1:1:22:3 | hello.rb | | hello.rb:2:5:4:7 | hello | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:3:9:3:22 | return | hello.rb:1:1:8:3 | EnglishWords | diff --git a/ruby/ql/test/library-tests/modules/superclasses.expected b/ruby/ql/test/library-tests/modules/superclasses.expected index 1a6504c1a79..f73f7962731 100644 --- a/ruby/ql/test/library-tests/modules/superclasses.expected +++ b/ruby/ql/test/library-tests/modules/superclasses.expected @@ -85,24 +85,24 @@ calls.rb: # 377| SingletonOverride1 #-----| -> Object -# 402| SingletonOverride2 +# 404| SingletonOverride2 #-----| -> SingletonOverride1 -# 417| ConditionalInstanceMethods +# 421| ConditionalInstanceMethods #-----| -> Object -# 480| ExtendSingletonMethod +# 484| ExtendSingletonMethod -# 490| ExtendSingletonMethod2 +# 494| ExtendSingletonMethod2 -# 496| ExtendSingletonMethod3 +# 500| ExtendSingletonMethod3 -# 509| ProtectedMethodInModule +# 513| ProtectedMethodInModule -# 515| ProtectedMethods +# 519| ProtectedMethods #-----| -> Object -# 534| ProtectedMethodsSub +# 538| ProtectedMethodsSub #-----| -> ProtectedMethods hello.rb: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 2c547c365ec..9f2cb351ed0 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 * Initial release. Extracted common SSA code into a library pack to share code between languages. diff --git a/shared/ssa/change-notes/released/0.0.2.md b/shared/ssa/change-notes/released/0.0.2.md new file mode 100644 index 00000000000..5ab250998ed --- /dev/null +++ b/shared/ssa/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index c6933410b71..55dc06fbd76 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index ef21714c8b8..3fc606ae5ed 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/ssa -version: 0.0.2-dev +version: 0.0.3-dev groups: shared library: true diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 95a5c570ac0..82994494b53 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.2 + +No user-facing changes. + ## 0.0.1 * Initial release. Share the database of common typographical errors between languages. diff --git a/shared/typos/change-notes/released/0.0.2.md b/shared/typos/change-notes/released/0.0.2.md new file mode 100644 index 00000000000..5ab250998ed --- /dev/null +++ b/shared/typos/change-notes/released/0.0.2.md @@ -0,0 +1,3 @@ +## 0.0.2 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index c6933410b71..55dc06fbd76 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.1 +lastReleaseVersion: 0.0.2 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 587537220ec..a8adea7ab70 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/typos -version: 0.0.2-dev +version: 0.0.3-dev groups: shared library: true diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 67e93ea7f6f..c8d9d66e1b9 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -163,7 +163,9 @@ abstract class Configuration extends string { /** * Holds if data may flow from some source to `sink` for this configuration. */ - predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) } + predicate hasFlowTo(Node sink) { + sink = any(PathNodeSink n | this = n.getConfiguration()).getNodeEx().asNode() + } /** * Holds if data may flow from some source to `sink` for this configuration.