python: use standard InstanceSource construction

This commit is contained in:
Rasmus Lerchedahl Petersen
2022-02-01 13:31:16 +01:00
parent 119a7e4f34
commit c587084758
3 changed files with 44 additions and 26 deletions

View File

@@ -2303,10 +2303,14 @@ module PrivateDjango {
* A standard Python logger instance from Django.
* see https://github.com/django/django/blob/stable/4.0.x/django/utils/log.py#L11
*/
private class DjangoLogger extends Stdlib::Logger::LoggerInstance {
private class DjangoLogger extends Stdlib::Logger::InstanceSource {
DjangoLogger() {
this =
API::moduleImport("django").getMember("utils").getMember("log").getMember("request_logger")
API::moduleImport("django")
.getMember("utils")
.getMember("log")
.getMember("request_logger")
.getAnImmediateUse()
}
}
}

View File

@@ -581,7 +581,7 @@ module Flask {
* - https://flask.palletsprojects.com/en/2.0.x/api/#flask.Flask.logger
* - https://flask.palletsprojects.com/en/2.0.x/logging/
*/
private class FlaskLogger extends Stdlib::Logger::LoggerInstance {
FlaskLogger() { this = FlaskApp::instance().getMember("logger") }
private class FlaskLogger extends Stdlib::Logger::InstanceSource {
FlaskLogger() { this = FlaskApp::instance().getMember("logger").getAnImmediateUse() }
}
}

View File

@@ -242,36 +242,48 @@ module Stdlib {
// logging
// ---------------------------------------------------------------------------
/**
* Provides models for the `logging.Logger` class and subclasses.
* Provides models for the `logging.Logger` class
*
* See https://docs.python.org/3.9/library/logging.html#logging.Logger.
*/
module Logger {
/**
* An instance of `logging.Logger`. Extend this class to model new instances.
* Most major frameworks will provide a logger instance as a class attribute.
*/
abstract class LoggerInstance extends API::Node {
override string toString() { result = "logger" }
}
/** Gets a reference to the `logging.Logger` class or any subclass. */
API::Node subclassRef() {
private API::Node subclassRef() {
result = API::moduleImport("logging").getMember("Logger").getASubclass*()
}
/** Gets a reference to an instance of `logging.Logger` or any subclass. */
API::Node instance() {
result instanceof LoggerInstance
or
result = subclassRef().getReturn()
or
result = API::moduleImport("logging")
or
result = API::moduleImport("logging").getMember("root")
or
result = API::moduleImport("logging").getMember("getLogger").getReturn()
/**
* A source of instances of `logging.Logger`, extend this class to model new instances.
*
* This can include instantiations of the class, return values from function
* calls, or a special parameter that will be set when functions are called by an external
* library.
*
* Use the predicate `Logger::instance()` to get references to instances of `logging.Logger`.
*/
abstract class InstanceSource extends DataFlow::LocalSourceNode { }
/** A direct instantiation of `logging.Logger`. */
private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode {
ClassInstantiation() {
this = subclassRef().getACall()
or
this = API::moduleImport("logging").getMember("root").getAnImmediateUse()
or
this = API::moduleImport("logging").getMember("getLogger").getACall()
}
}
/** Gets a reference to an instance of `logging.Logger`. */
private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) {
t.start() and
result instanceof InstanceSource
or
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
}
/** Gets a reference to an instance of `logging.Logger`. */
DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) }
}
}
@@ -2698,7 +2710,9 @@ private module StdlibPrivate {
method = "log" and
msgIndex = 1
|
this = Stdlib::Logger::instance().getMember(method).getACall()
this.(DataFlow::MethodCallNode).calls(Stdlib::Logger::instance(), method)
or
this = API::moduleImport("logging").getMember(method).getACall()
)
}