diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index f819e867907..cdfd1b454a1 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -71,14 +71,21 @@ module Flask { * See https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask. */ module FlaskApp { - /** Gets a reference to the `flask.Flask` class. */ - API::Node classRef() { - result = API::moduleImport("flask").getMember("Flask") or + /** + * Gets a reference to the `flask.Flask` class or any subclass. + * + * Deprecated: Use `subclassRef()` instead, this predicate always returned some subclasses. + */ + deprecated API::Node classRef() { result = subclassRef() } + + /** Gets a reference to the `flask.Flask` class or any subclass. */ + API::Node subclassRef() { + result = API::moduleImport("flask").getMember("Flask").getASubclass*() or result = ModelOutput::getATypeNode("flask.Flask~Subclass").getASubclass*() } /** Gets a reference to an instance of `flask.Flask` (a flask application). */ - API::Node instance() { result = classRef().getReturn() } + API::Node instance() { result = subclassRef().getReturn() } } /** @@ -132,7 +139,7 @@ module Flask { API::Node classRef() { result = API::moduleImport("flask").getMember("Response") or - result = [FlaskApp::classRef(), FlaskApp::instance()].getMember("response_class") + result = [FlaskApp::subclassRef(), FlaskApp::instance()].getMember("response_class") or result = ModelOutput::getATypeNode("flask.Response~Subclass").getASubclass*() } diff --git a/python/ql/src/meta/ClassHierarchy/Find.ql b/python/ql/src/meta/ClassHierarchy/Find.ql index 2c474cb2102..e13c683b6f1 100644 --- a/python/ql/src/meta/ClassHierarchy/Find.ql +++ b/python/ql/src/meta/ClassHierarchy/Find.ql @@ -351,7 +351,7 @@ class DjangoHttpRequest extends FindSubclassesSpec { class FlaskClass extends FindSubclassesSpec { FlaskClass() { this = "flask.Flask~Subclass" } - override API::Node getAlreadyModeledClass() { result = Flask::FlaskApp::classRef() } + override API::Node getAlreadyModeledClass() { result = Flask::FlaskApp::subclassRef() } } class FlaskBlueprint extends FindSubclassesSpec { diff --git a/python/ql/test/library-tests/frameworks/flask/flask_subclass.py b/python/ql/test/library-tests/frameworks/flask/flask_subclass.py index 03199077989..145adada0ae 100644 --- a/python/ql/test/library-tests/frameworks/flask/flask_subclass.py +++ b/python/ql/test/library-tests/frameworks/flask/flask_subclass.py @@ -6,9 +6,9 @@ class Sub(Flask): Flask.__init__(self, *args, **kwargs) -app = Sub(__name__) # $ MISSING: instance +app = Sub(__name__) # $ instance -@app.route("/") -def hello(): - return "world" \ No newline at end of file +@app.route("/") # $ routeSetup="/" +def hello(): # $ requestHandler + return "world" # $ HttpResponse \ No newline at end of file