Python: Add API::EntryPoint

Python: add EntryPoint test
This commit is contained in:
Asger F
2022-09-02 13:14:49 +02:00
parent 55fdf84d15
commit 296aa52ef0
3 changed files with 60 additions and 1 deletions

View File

@@ -453,6 +453,30 @@ module API {
int getNumArgument() { result = count(this.getArg(_)) }
}
/**
* An API entry point.
*
* By default, API graph nodes are only created for nodes that come from an external
* library or escape into an external library. The points where values are cross the boundary
* between codebases are called "entry points".
*
* Anything imported from an external package is considered to be an entry point, but
* additional entry points may be added by extending this class.
*/
abstract class EntryPoint extends string {
bindingset[this]
EntryPoint() { any() }
/** Gets a data-flow node corresponding to a use-node for this entry point. */
DataFlow::LocalSourceNode getASource() { none() }
/** Gets a data-flow node corresponding to a def-node for this entry point. */
DataFlow::Node getASink() { none() }
/** Gets an API-node for this entry point. */
API::Node getANode() { result = root().getASuccessor(Label::entryPoint(this)) }
}
/**
* Provides the actual implementation of API graphs, cached for performance.
*
@@ -652,6 +676,12 @@ module API {
|
lbl = Label::memberFromRef(aw)
)
or
exists(EntryPoint entry |
base = root() and
lbl = Label::entryPoint(entry) and
rhs = entry.getASink()
)
}
/**
@@ -735,6 +765,12 @@ module API {
ImportStar::namePossiblyDefinedInImportStar(ref.asCfgNode(), name, s)
))
)
or
exists(EntryPoint entry |
base = root() and
lbl = Label::entryPoint(entry) and
ref = entry.getASource()
)
}
/**
@@ -909,7 +945,8 @@ module API {
MkLabelSelfParameter() or
MkLabelReturn() or
MkLabelSubclass() or
MkLabelAwait()
MkLabelAwait() or
MkLabelEntryPoint(EntryPoint ep)
/** A label for a module. */
class LabelModule extends ApiLabel, MkLabelModule {
@@ -983,6 +1020,15 @@ module API {
class LabelAwait extends ApiLabel, MkLabelAwait {
override string toString() { result = "getAwaited()" }
}
/** A label for entry points. */
class LabelEntryPoint extends ApiLabel, MkLabelEntryPoint {
private EntryPoint entry;
LabelEntryPoint() { this = MkLabelEntryPoint(entry) }
override string toString() { result = "entryPoint(\"" + entry + "\")" }
}
}
/** Gets the edge label for the module `m`. */
@@ -1019,5 +1065,8 @@ module API {
/** Gets the `await` edge label. */
LabelAwait await() { any() }
/** Gets the label going from the root node to the nodes associated with the given entry point. */
LabelEntryPoint entryPoint(EntryPoint ep) { result = MkLabelEntryPoint(ep) }
}
}

View File

@@ -0,0 +1,2 @@
"magic_string".foo.bar #$ use=entryPoint("CustomEntryPoint").getMember("foo").getMember("bar")
"magic_string2".foo.bar

View File

@@ -1,3 +1,11 @@
// Note: This is not using standard inline-expectation tests, so will not alert if you
// have not manually added an annotation to a line!
import TestUtilities.VerifyApiGraphs
class CustomEntryPoint extends API::EntryPoint {
CustomEntryPoint() { this = "CustomEntryPoint" }
override DataFlow::LocalSourceNode getASource() {
result.asExpr().(StrConst).getText() = "magic_string"
}
}