Python: Remove status code modeling

I'm not even trying to model it properly right now, and don't have a specific
use-case for it RIGHT NOW. I think we could want this in the future, but I think
it's probably better to model it when we know what we want to use it for.
This commit is contained in:
Rasmus Wriedt Larsen
2020-10-22 13:36:24 +02:00
parent 19dc04de3c
commit 35334cf630
4 changed files with 18 additions and 50 deletions

View File

@@ -239,9 +239,6 @@ module HTTP {
/** Gets the content-type of this HTTP response, if it can be statically determined. */
string getContentType() { result = range.getContentType() }
/** Gets the status code of this HTTP response, if it can be statically determined. */
int getStatusCode() { result = range.getStatusCode() }
}
/** Provides a class for modeling new HTTP response APIs. */
@@ -275,23 +272,6 @@ module HTTP {
not exists(this.getContentTypeArg()) and
result = this.getContentTypeDefault()
}
/** Gets the data-flow node that specifies the status code of this HTTP response, if any. */
abstract DataFlow::Node getStatusCodeArg();
/** Gets the default status code that should be used if `getStatusCodeArg` has no results. */
abstract int getStatusCodeDefault();
/** Gets the status code of this HTTP response, if it can be statically determined. */
int getStatusCode() {
exists(IntegerLiteral i |
DataFlow::localFlow(DataFlow::exprNode(i), this.getStatusCodeArg()) and
result = i.getValue()
)
or
not exists(this.getStatusCodeArg()) and
result = this.getStatusCodeDefault()
}
}
}
}

View File

@@ -394,9 +394,5 @@ private module FlaskModel {
override string getContentTypeDefault() { result = "text/html" }
override DataFlow::Node getContentTypeArg() { none() }
override int getStatusCodeDefault() { result = 200 }
override DataFlow::Node getStatusCodeArg() { result.asCfgNode() = node.getArg(1) }
}
}

View File

@@ -7,7 +7,7 @@ app = Flask(__name__)
@app.route("/html1") # $routeSetup="/html1"
def html1(): # $routeHandler
return "<h1>hello</h1>" # $f-:HttpResponse $f-:contentType=text/html $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
return "<h1>hello</h1>" # $f-:HttpResponse $f-:contentType=text/html $f-:responseBody="<h1>hello</h1>"
@app.route("/html2") # $routeSetup="/html2"
@@ -15,13 +15,13 @@ def html2(): # $routeHandler
# note that response saved in a variable intentionally -- we wan the annotations to
# show that we recognize the response creation, and not the return (hopefully). (and
# do the same in the following of the file)
resp = make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $statusCode=200 $responseBody="<h1>hello</h1>"
resp = make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $responseBody="<h1>hello</h1>"
return resp
@app.route("/html3") # $routeSetup="/html3"
def html3(): # $routeHandler
resp = app.make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $statusCode=200 $responseBody="<h1>hello</h1>"
resp = app.make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $responseBody="<h1>hello</h1>"
return resp
@@ -31,7 +31,7 @@ def html3(): # $routeHandler
@app.route("/html4") # $routeSetup="/html4"
def html4(): # $routeHandler
resp = Response("<h1>hello</h1>") # $f-:HttpResponse $f-:contentType=text/html $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = Response("<h1>hello</h1>") # $f-:HttpResponse $f-:contentType=text/html $f-:responseBody="<h1>hello</h1>"
return resp
@@ -39,7 +39,7 @@ def html4(): # $routeHandler
def html5(): # $routeHandler
# note: flask.Flask.response_class is set to `flask.Response` by default.
# it can be overridden, but we don't try to handle that right now.
resp = Flask.response_class("<h1>hello</h1>") # $f-:HttpResponse $f-:contentType=text/html $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = Flask.response_class("<h1>hello</h1>") # $f-:HttpResponse $f-:contentType=text/html $f-:responseBody="<h1>hello</h1>"
return resp
@@ -47,14 +47,14 @@ def html5(): # $routeHandler
def html6(): # $routeHandler
# note: app.response_class (flask.Flask.response_class) is set to `flask.Response` by default.
# it can be overridden, but we don't try to handle that right now.
resp = app.response_class("<h1>hello</h1>") # $f-:HttpResponse $f-:contentType=text/html $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = app.response_class("<h1>hello</h1>") # $f-:HttpResponse $f-:contentType=text/html $f-:responseBody="<h1>hello</h1>"
return resp
@app.route("/jsonify") # $routeSetup="/jsonify"
def jsonify_route(): # $routeHandler
data = {"foo": "bar"}
response = jsonify(data) # $f-:HttpResponse $f-:contentType=application/json $f-:statusCode=200 $f-:responseBody=data
response = jsonify(data) # $f-:HttpResponse $f-:contentType=application/json $f-:responseBody=data
return response
@@ -65,14 +65,14 @@ def jsonify_route(): # $routeHandler
@app.route("/content-type/response-modification1") # $routeSetup="/content-type/response-modification1"
def response_modification1(): # $routeHandler
resp = make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $statusCode=200 $responseBody="<h1>hello</h1>"
resp = make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $responseBody="<h1>hello</h1>"
resp.content_type = "text/plain" # $f-:HttpResponse $f-:contentType=text/plain
return resp
@app.route("/content-type/response-modification2") # $routeSetup="/content-type/response-modification2"
def response_modification2(): # $routeHandler
resp = make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $statusCode=200 $responseBody="<h1>hello</h1>"
resp = make_response("<h1>hello</h1>") # $HttpResponse $contentType=text/html $responseBody="<h1>hello</h1>"
resp.headers["content-type"] = "text/plain" # $f-:HttpResponse $f-:contentType=text/plain
return resp
@@ -83,13 +83,13 @@ def response_modification2(): # $routeHandler
@app.route("/content-type/Response1") # $routeSetup="/content-type/Response1"
def Response1(): # $routeHandler
resp = Response("<h1>hello</h1>", mimetype="text/plain") # $f-:HttpResponse $f-:contentType=text/plain $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = Response("<h1>hello</h1>", mimetype="text/plain") # $f-:HttpResponse $f-:contentType=text/plain $f-:responseBody="<h1>hello</h1>"
return resp
@app.route("/content-type/Response2") # $routeSetup="/content-type/Response2"
def Response2(): # $routeHandler
resp = Response("<h1>hello</h1>", content_type="text/plain; charset=utf-8") # $f-:HttpResponse $f-:contentType=text/plain $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = Response("<h1>hello</h1>", content_type="text/plain; charset=utf-8") # $f-:HttpResponse $f-:contentType=text/plain $f-:responseBody="<h1>hello</h1>"
return resp
@@ -98,14 +98,14 @@ def Response3(): # $routeHandler
# content_type argument takes priority (and result is text/plain)
resp = Response(
"<h1>hello</h1>", content_type="text/plain; charset=utf-8", mimetype="text/html"
) # $f-:HttpResponse $f-:contentType=text/plain $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
) # $f-:HttpResponse $f-:contentType=text/plain $f-:responseBody="<h1>hello</h1>"
return resp
@app.route("/content-type/Response4") # $routeSetup="/content-type/Response4"
def Response4(): # $routeHandler
# note: capitalization of Content-Type does not matter
resp = Response("<h1>hello</h1>", headers={"Content-TYPE": "text/plain"}) # $f-:HttpResponse $f-:contentType=text/plain $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = Response("<h1>hello</h1>", headers={"Content-TYPE": "text/plain"}) # $f-:HttpResponse $f-:contentType=text/plain $f-:responseBody="<h1>hello</h1>"
return resp
@@ -115,7 +115,7 @@ def Response5(): # $routeHandler
# note: capitalization of Content-Type does not matter
resp = Response(
"<h1>hello</h1>", headers={"Content-TYPE": "text/html"}, content_type="text/plain; charset=utf-8"
) # $f-:HttpResponse $f-:contentType=text/plain $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
) # $f-:HttpResponse $f-:contentType=text/plain $f-:responseBody="<h1>hello</h1>"
return resp
@@ -123,7 +123,7 @@ def Response5(): # $routeHandler
def Flask_response_class(): # $routeHandler
# note: flask.Flask.response_class is set to `flask.Response` by default.
# it can be overridden, but we don't try to handle that right now.
resp = Flask.response_class("<h1>hello</h1>", mimetype="text/plain") # $f-:HttpResponse $f-:contentType=text/plain $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = Flask.response_class("<h1>hello</h1>", mimetype="text/plain") # $f-:HttpResponse $f-:contentType=text/plain $f-:responseBody="<h1>hello</h1>"
return resp
@@ -131,9 +131,10 @@ def Flask_response_class(): # $routeHandler
def app_response_class(): # $routeHandler
# note: app.response_class (flask.Flask.response_class) is set to `flask.Response` by default.
# it can be overridden, but we don't try to handle that right now.
resp = app.response_class("<h1>hello</h1>", mimetype="text/plain") # $f-:HttpResponse $f-:contentType=text/plain $f-:statusCode=200 $f-:responseBody="<h1>hello</h1>"
resp = app.response_class("<h1>hello</h1>", mimetype="text/plain") # $f-:HttpResponse $f-:contentType=text/plain $f-:responseBody="<h1>hello</h1>"
return resp
# TODO: add tests for setting status code
# TODO: add test that manually creates a redirect by setting status code and suitable header.

View File

@@ -148,9 +148,7 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest {
HttpServerHttpResponseTest() { this = "HttpServerHttpResponseTest: " + file }
override string getARelevantTag() {
result in ["HttpResponse", "responseBody", "contentType", "statusCode"]
}
override string getARelevantTag() { result in ["HttpResponse", "responseBody", "contentType"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
// By adding `file` as a class field, and these two restrictions, it's possible to
@@ -180,13 +178,6 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest {
value = response.getContentType() and
tag = "contentType"
)
or
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = response.getStatusCode().toString() and
tag = "statusCode"
)
)
}
}