mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' of https://github.com/github/codeql into oscarsj/merge-back-rc-3.20
This commit is contained in:
@@ -75,6 +75,9 @@ module MakeImplContentDataFlow<LocationSig Location, InputSig<Location> Lang> {
|
||||
/** Gets a limit on the number of reads out of sources and number of stores into sinks. */
|
||||
default int accessPathLimit() { result = Lang::accessPathLimit() }
|
||||
|
||||
/** Gets the access path limit used in the internal invocation of the standard data flow library. */
|
||||
default int accessPathLimitInternal() { result = Lang::accessPathLimit() }
|
||||
|
||||
/** Holds if `c` is relevant for reads out of sources or stores into sinks. */
|
||||
default predicate isRelevantContent(ContentSet c) { any() }
|
||||
}
|
||||
@@ -110,7 +113,7 @@ module MakeImplContentDataFlow<LocationSig Location, InputSig<Location> Lang> {
|
||||
|
||||
FlowFeature getAFeature() { result = ContentConfig::getAFeature() }
|
||||
|
||||
predicate accessPathLimit = ContentConfig::accessPathLimit/0;
|
||||
predicate accessPathLimit = ContentConfig::accessPathLimitInternal/0;
|
||||
|
||||
// needed to record reads/stores inside summarized callables
|
||||
predicate includeHiddenNodes() { any() }
|
||||
@@ -274,6 +277,16 @@ module MakeImplContentDataFlow<LocationSig Location, InputSig<Location> Lang> {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of this access path.
|
||||
*/
|
||||
int length() {
|
||||
this = TAccessPathNil() and
|
||||
result = 0
|
||||
or
|
||||
result = this.getTail().length() + 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the content set at index `i` in this access path, if any.
|
||||
*/
|
||||
|
||||
@@ -207,6 +207,28 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
|
||||
flowLocal(source, sink) and Config::observeOverlayInformedIncrementalMode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `source` to some sink.
|
||||
* This is a local predicate that only has results local to the overlay/base database.
|
||||
*/
|
||||
predicate flowFromLocal(Node source) = forceLocal(Flow::flowFrom/1)(source)
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `source` to some sink.
|
||||
*/
|
||||
predicate flowFrom(Node source) {
|
||||
Flow::flowFrom(source)
|
||||
or
|
||||
// If we are overlay informed (i.e. we are not diff-informed), we
|
||||
// merge in the local results which includes the base database results.
|
||||
flowFromLocal(source) and Config::observeOverlayInformedIncrementalMode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `source` to some sink.
|
||||
*/
|
||||
predicate flowFromExpr(Lang::DataFlowExpr source) { flowFrom(exprNode(source)) }
|
||||
|
||||
/**
|
||||
* Holds if data can flow from some source to `sink`.
|
||||
* This is a local predicate that only has results local to the overlay/base database.
|
||||
@@ -3501,6 +3523,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `source` to some sink.
|
||||
*/
|
||||
predicate flowFrom(Node source) { exists(PathNode n | n.isSource() and n.getNode() = source) }
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `source` to some sink.
|
||||
*/
|
||||
predicate flowFromExpr(Expr source) { flowFrom(exprNode(source)) }
|
||||
|
||||
/**
|
||||
* Holds if data can flow from some source to `sink`.
|
||||
*/
|
||||
|
||||
@@ -74,6 +74,9 @@ signature module InputSig<LocationSig Location, DF::InputSig<Location> DataFlowL
|
||||
) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if `(n1, n2)` should be excluded from the consistency test `localFlowIsLocal`. */
|
||||
default predicate localFlowIsLocalExclude(DataFlowLang::Node n1, DataFlowLang::Node n2) { none() }
|
||||
}
|
||||
|
||||
module MakeConsistency<
|
||||
@@ -169,6 +172,7 @@ module MakeConsistency<
|
||||
query predicate localFlowIsLocal(Node n1, Node n2, string msg) {
|
||||
simpleLocalFlowStep(n1, n2, _) and
|
||||
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
|
||||
not Input::localFlowIsLocalExclude(n1, n2) and
|
||||
msg = "Local flow step does not preserve enclosing callable."
|
||||
}
|
||||
|
||||
@@ -240,6 +244,13 @@ module MakeConsistency<
|
||||
|
||||
private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) }
|
||||
|
||||
/**
|
||||
* Consider code like `a.b.f = source()`. There is flow from `source()` to
|
||||
* `[post] a.b` (with an appropriate access path), but we also want there to
|
||||
* be flow to `[post] a` (with an appropriate access path). The data flow
|
||||
* library is able to infer this step because there is a read step from `a`
|
||||
* to `a.b`, as long as the post-update node for `a` exists.
|
||||
*/
|
||||
query predicate reverseRead(Node n, string msg) {
|
||||
exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and
|
||||
not Input::reverseReadExclude(n) and
|
||||
|
||||
Reference in New Issue
Block a user