mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Python: Make API graph version of PEP249 modeling
This will allow us to more easily handle the executescript method, which we'll do in next commit.
This commit is contained in:
@@ -561,8 +561,8 @@ module PrivateDjango {
|
||||
API::Node connection() { result = db().getMember("connection") }
|
||||
|
||||
/** A `django.db.connection` is a PEP249 compliant DB connection. */
|
||||
class DjangoDbConnection extends PEP249::Connection::InstanceSource {
|
||||
DjangoDbConnection() { this = connection().asSource() }
|
||||
class DjangoDbConnection extends PEP249::DatabaseConnection {
|
||||
DjangoDbConnection() { this = connection() }
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -22,6 +22,67 @@ module PEP249 {
|
||||
override string toString() { result = this.(API::Node).toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An API graph node representing a database connection.
|
||||
*/
|
||||
abstract class DatabaseConnection extends API::Node {
|
||||
/** Gets a string representation of this element. */
|
||||
override string toString() { result = this.(API::Node).toString() }
|
||||
}
|
||||
|
||||
private class DefaultDatabaseConnection extends DatabaseConnection {
|
||||
DefaultDatabaseConnection() {
|
||||
this = any(PEP249ModuleApiNode mod).getMember("connect").getReturn()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An API graph node representing a database cursor.
|
||||
*/
|
||||
abstract class DatabaseCursor extends API::Node {
|
||||
/** Gets a string representation of this element. */
|
||||
override string toString() { result = this.(API::Node).toString() }
|
||||
}
|
||||
|
||||
private class DefaultDatabaseCursor extends DatabaseCursor {
|
||||
DefaultDatabaseCursor() { this = any(DatabaseConnection conn).getMember("cursor").getReturn() }
|
||||
}
|
||||
|
||||
private string getSqlKwargName() {
|
||||
result in ["sql", "statement", "operation", "query", "query_string"]
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `execute` or `executemany` method on a database cursor or a connection.
|
||||
*
|
||||
* See
|
||||
* - https://peps.python.org/pep-0249/#execute
|
||||
* - https://peps.python.org/pep-0249/#executemany
|
||||
*
|
||||
* Note: While `execute` method on a connection is not part of PEP249, if it is used, we
|
||||
* recognize it as an alias for constructing a cursor and calling `execute` on it.
|
||||
*/
|
||||
private class ExecuteMethodCall extends SqlExecution::Range, API::CallNode {
|
||||
ExecuteMethodCall() {
|
||||
exists(API::Node start |
|
||||
start instanceof DatabaseCursor or start instanceof DatabaseConnection
|
||||
|
|
||||
this = start.getMember(["execute", "executemany"]).getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getSql() {
|
||||
result in [this.getArg(0), this.getArgByName(getSqlKwargName()),]
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// old impl
|
||||
// ---------------------------------------------------------------------------
|
||||
// the goal is to deprecate it in favour of the API graph version, but currently this
|
||||
// requires a rewrite of the Peewee modeling, which depends on rewriting the
|
||||
// instance/instance-source stuff to use API graphs instead.
|
||||
// so is postponed for now.
|
||||
/** Gets a reference to the `connect` function of a module that implements PEP 249. */
|
||||
DataFlow::Node connect() {
|
||||
result = any(PEP249ModuleApiNode a).getMember("connect").getAValueReachableFromSource()
|
||||
@@ -147,7 +208,10 @@ module PEP249 {
|
||||
* recognize it as an alias for constructing a cursor and calling `execute` on it.
|
||||
*/
|
||||
private class ExecuteCall extends SqlExecution::Range, DataFlow::CallCfgNode {
|
||||
ExecuteCall() { this.getFunction() = execute() }
|
||||
ExecuteCall() {
|
||||
this.getFunction() = execute() and
|
||||
not this instanceof ExecuteMethodCall
|
||||
}
|
||||
|
||||
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] }
|
||||
}
|
||||
@@ -170,8 +234,13 @@ module PEP249 {
|
||||
* recognize it as an alias for constructing a cursor and calling `executemany` on it.
|
||||
*/
|
||||
private class ExecutemanyCall extends SqlExecution::Range, DataFlow::CallCfgNode {
|
||||
ExecutemanyCall() { this.getFunction() = executemany() }
|
||||
ExecutemanyCall() {
|
||||
this.getFunction() = executemany() and
|
||||
not this instanceof ExecuteMethodCall
|
||||
}
|
||||
|
||||
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] }
|
||||
override DataFlow::Node getSql() {
|
||||
result in [this.getArg(0), this.getArgByName(getSqlKwargName())]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,11 +163,9 @@ private module Peewee {
|
||||
* A call to the `connection` method on a `peewee.Database` instance.
|
||||
* https://docs.peewee-orm.com/en/latest/peewee/api.html#Database.connection.
|
||||
*/
|
||||
class PeeweeDatabaseConnectionCall extends PEP249::Connection::InstanceSource,
|
||||
DataFlow::CallCfgNode
|
||||
{
|
||||
class PeeweeDatabaseConnectionCall extends PEP249::DatabaseConnection {
|
||||
PeeweeDatabaseConnectionCall() {
|
||||
this = Database::instance().getMember("connection").getACall()
|
||||
this = Database::instance().getMember("connection").getReturn()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,8 +173,8 @@ private module Peewee {
|
||||
* A call to the `cursor` method on a `peewee.Database` instance.
|
||||
* https://docs.peewee-orm.com/en/latest/peewee/api.html#Database.cursor.
|
||||
*/
|
||||
class PeeweeDatabaseCursorCall extends PEP249::Cursor::InstanceSource, DataFlow::CallCfgNode {
|
||||
PeeweeDatabaseCursorCall() { this = Database::instance().getMember("cursor").getACall() }
|
||||
class PeeweeDatabaseCursorCall extends PEP249::DatabaseCursor {
|
||||
PeeweeDatabaseCursorCall() { this = Database::instance().getMember("cursor").getReturn() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user