mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
87 lines
2.5 KiB
Plaintext
87 lines
2.5 KiB
Plaintext
/**
|
|
* Contains utility methods and classes to assist with generating data extensions models.
|
|
*/
|
|
|
|
private import python
|
|
private import semmle.python.ApiGraphs
|
|
private import semmle.python.filters.Tests
|
|
|
|
/**
|
|
* A file that probably contains tests.
|
|
*/
|
|
class TestFile extends File {
|
|
TestFile() {
|
|
this.getRelativePath().regexpMatch(".*(test|spec|examples).+") and
|
|
not this.getAbsolutePath().matches("%/ql/test/%") // allows our test cases to work
|
|
}
|
|
}
|
|
|
|
/** A class to represent scopes that the user might want to model. */
|
|
class RelevantScope extends Scope {
|
|
RelevantScope() {
|
|
this.isPublic() and
|
|
not this instanceof TestScope and
|
|
not this.getLocation().getFile() instanceof TestFile and
|
|
exists(this.getLocation().getFile().getRelativePath())
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the dotted path of a scope.
|
|
*/
|
|
string computeScopePath(RelevantScope scope) {
|
|
// base case
|
|
if scope instanceof Module
|
|
then
|
|
scope.(Module).isPackageInit() and
|
|
result = scope.(Module).getPackageName()
|
|
or
|
|
not scope.(Module).isPackageInit() and
|
|
result = scope.(Module).getName()
|
|
else
|
|
//recursive cases
|
|
if scope instanceof Class or scope instanceof Function
|
|
then result = computeScopePath(scope.getEnclosingScope()) + "." + scope.getName()
|
|
else result = "unknown: " + scope.toString()
|
|
}
|
|
|
|
signature predicate modelSig(string type, string path);
|
|
|
|
/**
|
|
* A utility module for finding models of endpoints.
|
|
*
|
|
* Chiefly the `hasModel` predicate is used to determine if a scope has a model.
|
|
*/
|
|
module FindModel<modelSig/2 model> {
|
|
/**
|
|
* Holds if the given scope has a model as identified by the provided predicate `model`.
|
|
*/
|
|
predicate hasModel(RelevantScope scope) {
|
|
exists(string type, string path, string searchPath | model(type, path) |
|
|
searchPath = possibleMemberPathPrefix(path, scope.getName()) and
|
|
pathToScope(scope, type, searchPath)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* returns the prefix of `path` that might be a path to `member`
|
|
*/
|
|
bindingset[path, member]
|
|
string possibleMemberPathPrefix(string path, string member) {
|
|
exists(int index | index = path.indexOf(["Member", "Method"] + "[" + member + "]") |
|
|
result = path.prefix(index)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Holds if `(type,path)` identifies `scope`.
|
|
*/
|
|
bindingset[type, path]
|
|
predicate pathToScope(RelevantScope scope, string type, string path) {
|
|
computeScopePath(scope) =
|
|
type.replaceAll("!", "") + "." +
|
|
path.replaceAll("Member[", "").replaceAll("]", "").replaceAll("Instance.", "") +
|
|
scope.getName()
|
|
}
|
|
}
|