mirror of
https://github.com/github/codeql.git
synced 2026-04-13 19:14:04 +02:00
None of these required any changes to the dataflow libraries, so it seemed easiest to put them in their own commit.
247 lines
7.7 KiB
Plaintext
247 lines
7.7 KiB
Plaintext
overlay[local?]
|
|
module;
|
|
|
|
private import python
|
|
private import semmle.python.dataflow.new.FlowSummary
|
|
private import semmle.python.ApiGraphs
|
|
|
|
/**
|
|
* This module ensures that the `callStep` predicate in
|
|
* our type tracker implelemtation does not refer to the
|
|
* `getACall` predicate on `SummarizedCallable`.
|
|
*/
|
|
module RecursionGuard {
|
|
private import semmle.python.dataflow.new.internal.TypeTrackingImpl::TypeTrackingInput as TT
|
|
|
|
private class RecursionGuard extends SummarizedCallable::Range {
|
|
RecursionGuard() { this = "RecursionGuard" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result.getFunction().asCfgNode().(NameNode).getId() = this and
|
|
(TT::callStep(_, _) implies any())
|
|
}
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
none()
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableIdentity extends SummarizedCallable::Range {
|
|
SummarizedCallableIdentity() { this = "identity" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result.getFunction().asCfgNode().(NameNode).getId() = this
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0]" and
|
|
output = "ReturnValue" and
|
|
preservesValue = true
|
|
}
|
|
}
|
|
|
|
// For lambda flow to work, implement lambdaCall and lambdaCreation
|
|
private class SummarizedCallableApplyLambda extends SummarizedCallable::Range {
|
|
SummarizedCallableApplyLambda() { this = "apply_lambda" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result.getFunction().asCfgNode().(NameNode).getId() = this
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[1]" and
|
|
output = "Argument[0].Parameter[0]" and
|
|
preservesValue = true
|
|
or
|
|
input = "Argument[0].ReturnValue" and
|
|
output = "ReturnValue" and
|
|
preservesValue = true
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableReversed extends SummarizedCallable::Range {
|
|
SummarizedCallableReversed() { this = "list_reversed" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result.getFunction().asCfgNode().(NameNode).getId() = this
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0].ListElement" and
|
|
output = "ReturnValue.ListElement" and
|
|
preservesValue = true
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableMap extends SummarizedCallable::Range {
|
|
SummarizedCallableMap() { this = "list_map" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result.getFunction().asCfgNode().(NameNode).getId() = this
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[1].ListElement" and
|
|
output = "Argument[0].Parameter[0]" and
|
|
preservesValue = true
|
|
or
|
|
input = "Argument[0].ReturnValue" and
|
|
output = "ReturnValue.ListElement" and
|
|
preservesValue = true
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableAppend extends SummarizedCallable::Range {
|
|
SummarizedCallableAppend() { this = "append_to_list" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result.getFunction().asCfgNode().(NameNode).getId() = this
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() { result.asExpr().(Name).getId() = this }
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0]" and
|
|
output = "ReturnValue" and
|
|
preservesValue = false
|
|
or
|
|
input = "Argument[1]" and
|
|
output = "ReturnValue.ListElement" and
|
|
preservesValue = true
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableJsonLoads extends SummarizedCallable::Range {
|
|
SummarizedCallableJsonLoads() { this = "json.loads" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result = API::moduleImport("json").getMember("loads").getACall()
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() {
|
|
result = API::moduleImport("json").getMember("loads").getAValueReachableFromSource()
|
|
}
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0]" and
|
|
output = "ReturnValue.ListElement" and
|
|
preservesValue = true
|
|
}
|
|
}
|
|
|
|
// Repeated summaries
|
|
private class SummarizedCallableWithSubpath extends SummarizedCallable::Range {
|
|
SummarizedCallableWithSubpath() { this = "extracted_package.functions.with_subpath" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("with_subpath")
|
|
.getACall()
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("with_subpath")
|
|
.getAValueReachableFromSource()
|
|
}
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0]" and
|
|
output = "ReturnValue" and
|
|
preservesValue = false
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableWithSubpathAgain extends SummarizedCallable::Range {
|
|
SummarizedCallableWithSubpathAgain() { this = "extracted_package.functions.with_subpathII" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("with_subpath")
|
|
.getACall()
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("with_subpath")
|
|
.getAValueReachableFromSource()
|
|
}
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0]" and
|
|
output = "ReturnValue.Attribute[pattern]" and
|
|
preservesValue = true
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableWithoutSubpath extends SummarizedCallable::Range {
|
|
SummarizedCallableWithoutSubpath() { this = "extracted_package.functions.without_subpath" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("without_subpath")
|
|
.getACall()
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("without_subpath")
|
|
.getAValueReachableFromSource()
|
|
}
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0]" and
|
|
output = "ReturnValue" and
|
|
preservesValue = false
|
|
}
|
|
}
|
|
|
|
private class SummarizedCallableWithoutSubpathAgain extends SummarizedCallable::Range {
|
|
SummarizedCallableWithoutSubpathAgain() { this = "extracted_package.functions.without_subpathII" }
|
|
|
|
override DataFlow::CallCfgNode getACall() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("without_subpath")
|
|
.getACall()
|
|
}
|
|
|
|
override DataFlow::ArgumentNode getACallback() {
|
|
result =
|
|
API::moduleImport("extracted_package")
|
|
.getMember("functions")
|
|
.getMember("without_subpath")
|
|
.getAValueReachableFromSource()
|
|
}
|
|
|
|
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
|
|
input = "Argument[0]" and
|
|
output = "ReturnValue.Attribute[pattern]" and
|
|
preservesValue = true
|
|
}
|
|
}
|