Skip to content

Commit babcf7a

Browse files
Rasmus Lerchedahl PetersenRasmus Lerchedahl Petersen
authored andcommitted
Python: add two implementations of PEP249
1 parent ae3227f commit babcf7a

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
private import python
2+
private import experimental.dataflow.DataFlow
3+
private import experimental.dataflow.RemoteFlowSources
4+
private import experimental.semmle.python.Concepts
5+
private import PEP249
6+
7+
// ---------------------------------------------------------------------------
8+
// MySQLdb
9+
// ---------------------------------------------------------------------------
10+
/** Gets a reference to the `MySQLdb` module. */
11+
private DataFlow::Node moduleMySQLdb(DataFlow::TypeTracker t) {
12+
t.start() and
13+
result = DataFlow::importNode("MySQLdb")
14+
or
15+
exists(DataFlow::TypeTracker t2 | result = moduleMySQLdb(t2).track(t2, t))
16+
}
17+
18+
/** Gets a reference to the `MySQLdb` module. */
19+
DataFlow::Node moduleMySQLdb() { result = moduleMySQLdb(DataFlow::TypeTracker::end()) }
20+
21+
class MySQLdb extends PEP249Module {
22+
MySQLdb() { this = moduleMySQLdb() }
23+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
private import python
2+
private import experimental.dataflow.DataFlow
3+
private import experimental.dataflow.RemoteFlowSources
4+
private import experimental.semmle.python.Concepts
5+
private import PEP249
6+
7+
// ---------------------------------------------------------------------------
8+
// mysql
9+
// ---------------------------------------------------------------------------
10+
/** Gets a reference to the `mysql` module. */
11+
private DataFlow::Node mysql(DataFlow::TypeTracker t) {
12+
t.start() and
13+
result = DataFlow::importNode("mysql")
14+
or
15+
exists(DataFlow::TypeTracker t2 | result = mysql(t2).track(t2, t))
16+
}
17+
18+
/** Gets a reference to the `mysql` module. */
19+
DataFlow::Node mysql() { result = mysql(DataFlow::TypeTracker::end()) }
20+
21+
/**
22+
* Gets a reference to the attribute `attr_name` of the `mysql` module.
23+
* WARNING: Only holds for a few predefined attributes.
24+
*/
25+
private DataFlow::Node mysql_attr(DataFlow::TypeTracker t, string attr_name) {
26+
attr_name in ["connector"] and
27+
(
28+
t.start() and
29+
result = DataFlow::importNode("mysql" + "." + attr_name)
30+
or
31+
t.startInAttr(attr_name) and
32+
result = mysql()
33+
)
34+
or
35+
// Due to bad performance when using normal setup with `mysql_attr(t2, attr_name).track(t2, t)`
36+
// we have inlined that code and forced a join
37+
exists(DataFlow::TypeTracker t2 |
38+
exists(DataFlow::StepSummary summary |
39+
mysql_attr_first_join(t2, attr_name, result, summary) and
40+
t = t2.append(summary)
41+
)
42+
)
43+
}
44+
45+
pragma[nomagic]
46+
private predicate mysql_attr_first_join(
47+
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary
48+
) {
49+
DataFlow::StepSummary::step(mysql_attr(t2, attr_name), res, summary)
50+
}
51+
52+
/**
53+
* Gets a reference to the attribute `attr_name` of the `mysql` module.
54+
* WARNING: Only holds for a few predefined attributes.
55+
*/
56+
private DataFlow::Node mysql_attr(string attr_name) {
57+
result = mysql_attr(DataFlow::TypeTracker::end(), attr_name)
58+
}
59+
60+
/** Provides models for the `mysql` module. */
61+
module mysql {
62+
class MysqlConnector extends PEP249Module {
63+
MysqlConnector() { this = mysql_attr("connector") }
64+
}
65+
}

0 commit comments

Comments
 (0)