Skip to content

Commit e5b68d6

Browse files
committed
Python: Use SqlConstruction in Asyncpg.qll
1 parent 03ada6e commit e5b68d6

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

python/ql/lib/semmle/python/frameworks/Asyncpg.qll

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ private module Asyncpg {
1818
/**
1919
* A `Connection` is created when
2020
* - the result of `asyncpg.connect()` is awaited.
21-
* - the result of calling `aquire` on a c=`ConnectionPool` is awaited.
21+
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
2222
*/
2323
API::Node connection() {
2424
result = API::moduleImport("asyncpg").getMember("connect").getReturn().getAwaited()
@@ -112,15 +112,17 @@ private module Asyncpg {
112112
* TODO: Rewrite this, once we have `API::CallNode` available.
113113
*/
114114
module PreparedStatement {
115+
class PreparedStatementConstruction extends SqlConstruction::Range, DataFlow::CallCfgNode {
116+
PreparedStatementConstruction() { this = connection().getMember("prepare").getACall() }
117+
118+
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("query")] }
119+
}
120+
115121
private DataFlow::TypeTrackingNode preparedStatementFactory(
116122
DataFlow::TypeTracker t, DataFlow::Node sql
117123
) {
118124
t.start() and
119-
result = connection().getMember("prepare").getACall() and
120-
sql in [
121-
result.(DataFlow::CallCfgNode).getArg(0),
122-
result.(DataFlow::CallCfgNode).getArgByName("query")
123-
]
125+
sql = result.(PreparedStatementConstruction).getSql()
124126
or
125127
exists(DataFlow::TypeTracker t2 | result = preparedStatementFactory(t2, sql).track(t2, t))
126128
}
@@ -163,14 +165,16 @@ private module Asyncpg {
163165
* TODO: Rewrite this, once we have `API::CallNode` available.
164166
*/
165167
module Cursor {
168+
class CursorConstruction extends SqlConstruction::Range, DataFlow::CallCfgNode {
169+
CursorConstruction() { this = connection().getMember("cursor").getACall() }
170+
171+
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("query")] }
172+
}
173+
166174
private DataFlow::TypeTrackingNode cursorFactory(DataFlow::TypeTracker t, DataFlow::Node sql) {
167175
// cursor created from connection
168176
t.start() and
169-
result = connection().getMember("cursor").getACall() and
170-
sql in [
171-
result.(DataFlow::CallCfgNode).getArg(0),
172-
result.(DataFlow::CallCfgNode).getArgByName("query")
173-
]
177+
sql = result.(CursorConstruction).getSql()
174178
or
175179
// cursor created from prepared statement
176180
t.start() and

python/ql/test/library-tests/frameworks/asyncpg/SqlExecution.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ async def test_prepared_statement():
2020
conn = await asyncpg.connect()
2121

2222
try:
23-
pstmt = await conn.prepare("psql")
23+
pstmt = await conn.prepare("psql") # $ constructedSql="psql"
2424
pstmt.executemany() # $ getSql="psql"
2525
pstmt.fetch() # $ getSql="psql"
2626
pstmt.fetchrow() # $ getSql="psql"
@@ -36,20 +36,20 @@ async def test_cursor():
3636

3737
try:
3838
async with conn.transaction():
39-
cursor = await conn.cursor("sql") # $ getSql="sql"
39+
cursor = await conn.cursor("sql") # $ getSql="sql" constructedSql="sql"
4040
await cursor.fetch()
4141

42-
pstmt = await conn.prepare("psql")
42+
pstmt = await conn.prepare("psql") # $ constructedSql="psql"
4343
pcursor = await pstmt.cursor() # $ getSql="psql"
4444
await pcursor.fetch()
4545

46-
async for record in conn.cursor("sql"): # $ getSql="sql"
46+
async for record in conn.cursor("sql"): # $ getSql="sql" constructedSql="sql"
4747
pass
4848

4949
async for record in pstmt.cursor(): # $ getSql="psql"
5050
pass
5151

52-
cursor_factory = conn.cursor("sql")
52+
cursor_factory = conn.cursor("sql") # $ constructedSql="sql"
5353
cursor = await cursor_factory # $ getSql="sql"
5454

5555
pcursor_factory = pstmt.cursor()

0 commit comments

Comments
 (0)