From ac411f1254a7783a2e13693b0b04dc5adef1d465 Mon Sep 17 00:00:00 2001 From: Kevin Stubbings Date: Wed, 30 Oct 2024 13:52:38 -0700 Subject: [PATCH] Second round feedback --- python/ql/lib/semmle/python/frameworks/Bottle.qll | 13 ++++++------- .../library-tests/frameworks/bottle/basic_test.py | 11 +++++++++++ .../bottle/{bottle_test.py => header_test.py} | 0 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 python/ql/test/library-tests/frameworks/bottle/basic_test.py rename python/ql/test/library-tests/frameworks/bottle/{bottle_test.py => header_test.py} (100%) diff --git a/python/ql/lib/semmle/python/frameworks/Bottle.qll b/python/ql/lib/semmle/python/frameworks/Bottle.qll index 6b16fcdd4c47..ce2a41dbaf4e 100644 --- a/python/ql/lib/semmle/python/frameworks/Bottle.qll +++ b/python/ql/lib/semmle/python/frameworks/Bottle.qll @@ -27,10 +27,7 @@ module Bottle { */ module App { /** Gets a reference to a Bottle application (an instance of `bottle.Bottle`) */ - API::Node instance() { result = bottle().getMember("Bottle").getReturn() } - - /** Gets a reference to a Bottle application (an instance of `bottle.app`) */ - API::Node app() { result = bottle().getMember("app").getReturn() } + API::Node app() { result = bottle().getMember(["Bottle", "app"]).getReturn() } } /** Provides models for functions that are possible "views" */ @@ -42,13 +39,13 @@ module Bottle { ViewCallable() { this = any(BottleRouteSetup rs).getARequestHandler() } } + /** Get methods that reprsent a route in Bottle */ string routeMethods() { result = ["route", "get", "post", "put", "delete", "patch"] } private class BottleRouteSetup extends Http::Server::RouteSetup::Range, DataFlow::CallCfgNode { BottleRouteSetup() { this = [ - App::instance().getMember(routeMethods()).getACall(), App::app().getMember(routeMethods()).getACall(), bottle().getMember(routeMethods()).getACall() ] @@ -68,8 +65,10 @@ module Bottle { /** Provides models for the `bottle.response` module */ module Response { - /** Gets a reference to the `bottle.response` module. */ - API::Node response() { result = bottle().getMember("response") } + /** Gets a reference to the `bottle.response` module or instantiation of Bottle Response class. */ + API::Node response() { + result = [bottle().getMember("response"), bottle().getMember("Response").getReturn()] + } /** A response returned by a view callable. */ class BottleReturnResponse extends Http::Server::HttpResponse::Range { diff --git a/python/ql/test/library-tests/frameworks/bottle/basic_test.py b/python/ql/test/library-tests/frameworks/bottle/basic_test.py new file mode 100644 index 000000000000..03bc15a027b2 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/bottle/basic_test.py @@ -0,0 +1,11 @@ +# Source: https://bottlepy.org/docs/dev/tutorial.html#the-application-object +from bottle import Bottle, run + +app = Bottle() + +@app.route('/hello') # $ routeSetup="/hello" +def hello(): # $ requestHandler + return "Hello World!" # $ HttpResponse responseBody="Hello World!" mimetype=text/html + +if __name__ == '__main__': + app.run(host='localhost', port=8080) \ No newline at end of file diff --git a/python/ql/test/library-tests/frameworks/bottle/bottle_test.py b/python/ql/test/library-tests/frameworks/bottle/header_test.py similarity index 100% rename from python/ql/test/library-tests/frameworks/bottle/bottle_test.py rename to python/ql/test/library-tests/frameworks/bottle/header_test.py