Skip to content

Commit 296aa52

Browse files
committed
Python: Add API::EntryPoint
Python: add EntryPoint test
1 parent 55fdf84 commit 296aa52

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

python/ql/lib/semmle/python/ApiGraphs.qll

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,30 @@ module API {
453453
int getNumArgument() { result = count(this.getArg(_)) }
454454
}
455455

456+
/**
457+
* An API entry point.
458+
*
459+
* By default, API graph nodes are only created for nodes that come from an external
460+
* library or escape into an external library. The points where values are cross the boundary
461+
* between codebases are called "entry points".
462+
*
463+
* Anything imported from an external package is considered to be an entry point, but
464+
* additional entry points may be added by extending this class.
465+
*/
466+
abstract class EntryPoint extends string {
467+
bindingset[this]
468+
EntryPoint() { any() }
469+
470+
/** Gets a data-flow node corresponding to a use-node for this entry point. */
471+
DataFlow::LocalSourceNode getASource() { none() }
472+
473+
/** Gets a data-flow node corresponding to a def-node for this entry point. */
474+
DataFlow::Node getASink() { none() }
475+
476+
/** Gets an API-node for this entry point. */
477+
API::Node getANode() { result = root().getASuccessor(Label::entryPoint(this)) }
478+
}
479+
456480
/**
457481
* Provides the actual implementation of API graphs, cached for performance.
458482
*
@@ -652,6 +676,12 @@ module API {
652676
|
653677
lbl = Label::memberFromRef(aw)
654678
)
679+
or
680+
exists(EntryPoint entry |
681+
base = root() and
682+
lbl = Label::entryPoint(entry) and
683+
rhs = entry.getASink()
684+
)
655685
}
656686

657687
/**
@@ -735,6 +765,12 @@ module API {
735765
ImportStar::namePossiblyDefinedInImportStar(ref.asCfgNode(), name, s)
736766
))
737767
)
768+
or
769+
exists(EntryPoint entry |
770+
base = root() and
771+
lbl = Label::entryPoint(entry) and
772+
ref = entry.getASource()
773+
)
738774
}
739775

740776
/**
@@ -909,7 +945,8 @@ module API {
909945
MkLabelSelfParameter() or
910946
MkLabelReturn() or
911947
MkLabelSubclass() or
912-
MkLabelAwait()
948+
MkLabelAwait() or
949+
MkLabelEntryPoint(EntryPoint ep)
913950

914951
/** A label for a module. */
915952
class LabelModule extends ApiLabel, MkLabelModule {
@@ -983,6 +1020,15 @@ module API {
9831020
class LabelAwait extends ApiLabel, MkLabelAwait {
9841021
override string toString() { result = "getAwaited()" }
9851022
}
1023+
1024+
/** A label for entry points. */
1025+
class LabelEntryPoint extends ApiLabel, MkLabelEntryPoint {
1026+
private EntryPoint entry;
1027+
1028+
LabelEntryPoint() { this = MkLabelEntryPoint(entry) }
1029+
1030+
override string toString() { result = "entryPoint(\"" + entry + "\")" }
1031+
}
9861032
}
9871033

9881034
/** Gets the edge label for the module `m`. */
@@ -1019,5 +1065,8 @@ module API {
10191065

10201066
/** Gets the `await` edge label. */
10211067
LabelAwait await() { any() }
1068+
1069+
/** Gets the label going from the root node to the nodes associated with the given entry point. */
1070+
LabelEntryPoint entryPoint(EntryPoint ep) { result = MkLabelEntryPoint(ep) }
10221071
}
10231072
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
"magic_string".foo.bar #$ use=entryPoint("CustomEntryPoint").getMember("foo").getMember("bar")
2+
"magic_string2".foo.bar
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
// Note: This is not using standard inline-expectation tests, so will not alert if you
22
// have not manually added an annotation to a line!
33
import TestUtilities.VerifyApiGraphs
4+
5+
class CustomEntryPoint extends API::EntryPoint {
6+
CustomEntryPoint() { this = "CustomEntryPoint" }
7+
8+
override DataFlow::LocalSourceNode getASource() {
9+
result.asExpr().(StrConst).getText() = "magic_string"
10+
}
11+
}

0 commit comments

Comments
 (0)