mirror of
https://github.com/github/codeql.git
synced 2026-01-29 22:32:58 +01:00
Merge pull request #522 from gagliardetto/fix-clevergo
Improve CleverGo models
This commit is contained in:
@@ -8,8 +8,6 @@ import go
|
||||
* Provides classes for working with concepts from the [`clevergo.tech/clevergo@v0.5.2`](https://pkg.go.dev/clevergo.tech/clevergo@v0.5.2) package.
|
||||
*/
|
||||
private module CleverGo {
|
||||
/** Gets the package path. */
|
||||
bindingset[result]
|
||||
string packagePath() {
|
||||
result = package(["clevergo.tech/clevergo", "github.com/clevergo/clevergo"], "")
|
||||
}
|
||||
@@ -192,188 +190,342 @@ private module CleverGo {
|
||||
|
||||
override DataFlow::Node getUrl() { result = urlNode }
|
||||
|
||||
override HTTP::ResponseWriter getResponseWriter() { none() }
|
||||
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Models HTTP ResponseBody.
|
||||
* Models HTTP ResponseBody where the content-type is static and non-modifiable.
|
||||
*/
|
||||
private class HttpResponseBody extends HTTP::ResponseBody::Range {
|
||||
string package;
|
||||
DataFlow::CallNode bodySetterCall;
|
||||
string contentType;
|
||||
private class HttpResponseBodyStaticContentType extends HTTP::ResponseBody::Range {
|
||||
string contentTypeString;
|
||||
DataFlow::Node receiverNode;
|
||||
|
||||
HttpResponseBody() {
|
||||
// HTTP ResponseBody models for package: clevergo.tech/clevergo@v0.5.2
|
||||
package = packagePath() and
|
||||
(
|
||||
// One call sets both body and content-type (which is implicit in the func name).
|
||||
// Receiver type: Context
|
||||
exists(string methodName, Method m |
|
||||
m.hasQualifiedName(package, "Context", methodName) and
|
||||
bodySetterCall = m.getACall()
|
||||
|
|
||||
// signature: func (*Context).Error(code int, msg string) error
|
||||
methodName = "Error" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).HTML(code int, html string) error
|
||||
methodName = "HTML" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "text/html"
|
||||
or
|
||||
// signature: func (*Context).HTMLBlob(code int, bs []byte) error
|
||||
methodName = "HTMLBlob" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "text/html"
|
||||
or
|
||||
// signature: func (*Context).JSON(code int, data interface{}) error
|
||||
methodName = "JSON" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "application/json"
|
||||
or
|
||||
// signature: func (*Context).JSONBlob(code int, bs []byte) error
|
||||
methodName = "JSONBlob" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "application/json"
|
||||
or
|
||||
// signature: func (*Context).JSONP(code int, data interface{}) error
|
||||
methodName = "JSONP" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).JSONPBlob(code int, bs []byte) error
|
||||
methodName = "JSONPBlob" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).JSONPCallback(code int, callback string, data interface{}) error
|
||||
methodName = "JSONPCallback" and
|
||||
this = bodySetterCall.getArgument(2) and
|
||||
contentType = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).JSONPCallbackBlob(code int, callback string, bs []byte) (err error)
|
||||
methodName = "JSONPCallbackBlob" and
|
||||
this = bodySetterCall.getArgument(2) and
|
||||
contentType = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).String(code int, s string) error
|
||||
methodName = "String" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).StringBlob(code int, bs []byte) error
|
||||
methodName = "StringBlob" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).Stringf(code int, format string, a ...interface{}) error
|
||||
methodName = "Stringf" and
|
||||
this = bodySetterCall.getArgument([1, any(int i | i >= 2)]) and
|
||||
contentType = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).XML(code int, data interface{}) error
|
||||
methodName = "XML" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "text/xml"
|
||||
or
|
||||
// signature: func (*Context).XMLBlob(code int, bs []byte) error
|
||||
methodName = "XMLBlob" and
|
||||
this = bodySetterCall.getArgument(1) and
|
||||
contentType = "text/xml"
|
||||
)
|
||||
or
|
||||
// One call sets both body and content-type (both are parameters in the func call).
|
||||
// Receiver type: Context
|
||||
exists(string methodName, Method m |
|
||||
m.hasQualifiedName(package, "Context", methodName) and
|
||||
bodySetterCall = m.getACall()
|
||||
|
|
||||
// signature: func (*Context).Blob(code int, contentType string, bs []byte) (err error)
|
||||
methodName = "Blob" and
|
||||
this = bodySetterCall.getArgument(2) and
|
||||
contentType = bodySetterCall.getArgument(1).getStringValue()
|
||||
or
|
||||
// signature: func (*Context).Emit(code int, contentType string, body string) (err error)
|
||||
methodName = "Emit" and
|
||||
this = bodySetterCall.getArgument(2) and
|
||||
contentType = bodySetterCall.getArgument(1).getStringValue()
|
||||
)
|
||||
or
|
||||
// Two calls, one to set the response body and one to set the content-type.
|
||||
// Receiver type: Context
|
||||
exists(string methodName, Method m |
|
||||
m.hasQualifiedName(package, "Context", methodName) and
|
||||
bodySetterCall = m.getACall()
|
||||
|
|
||||
// signature: func (*Context).Write(data []byte) (int, error)
|
||||
methodName = "Write" and
|
||||
this = bodySetterCall.getArgument(0)
|
||||
or
|
||||
// signature: func (*Context).WriteString(data string) (int, error)
|
||||
methodName = "WriteString" and
|
||||
this = bodySetterCall.getArgument(0)
|
||||
) and
|
||||
(
|
||||
// Receiver type: Context
|
||||
exists(string methodName, Method m, DataFlow::CallNode contentTypeSetterCall |
|
||||
m.hasQualifiedName(package, "Context", methodName) and
|
||||
contentTypeSetterCall = m.getACall() and
|
||||
contentTypeSetterCall.getReceiver().getAPredecessor*() =
|
||||
bodySetterCall.getReceiver().getAPredecessor*()
|
||||
|
|
||||
// signature: func (*Context).SetContentType(v string)
|
||||
methodName = "SetContentType" and
|
||||
contentType = contentTypeSetterCall.getArgument(0).getStringValue()
|
||||
)
|
||||
or
|
||||
// Receiver type: Context
|
||||
exists(string methodName, Method m, DataFlow::CallNode contentTypeSetterCall |
|
||||
m.hasQualifiedName(package, "Context", methodName) and
|
||||
contentTypeSetterCall = m.getACall() and
|
||||
contentTypeSetterCall.getReceiver().getAPredecessor*() =
|
||||
bodySetterCall.getReceiver().getAPredecessor*()
|
||||
|
|
||||
// signature: func (*Context).SetContentTypeHTML()
|
||||
methodName = "SetContentTypeHTML" and
|
||||
contentType = "text/html"
|
||||
or
|
||||
// signature: func (*Context).SetContentTypeJSON()
|
||||
methodName = "SetContentTypeJSON" and
|
||||
contentType = "application/json"
|
||||
or
|
||||
// signature: func (*Context).SetContentTypeText()
|
||||
methodName = "SetContentTypeText" and
|
||||
contentType = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).SetContentTypeXML()
|
||||
methodName = "SetContentTypeXML" and
|
||||
contentType = "text/xml"
|
||||
)
|
||||
)
|
||||
HttpResponseBodyStaticContentType() {
|
||||
exists(string package, string receiverName |
|
||||
setsBodyAndStaticContentType(package, receiverName, this, contentTypeString, receiverNode)
|
||||
)
|
||||
}
|
||||
|
||||
override string getAContentType() { result = contentType }
|
||||
override string getAContentType() { result = contentTypeString }
|
||||
|
||||
override HTTP::ResponseWriter getResponseWriter() { none() }
|
||||
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
|
||||
}
|
||||
|
||||
// Holds for a call that sets the body; the content-type is implicitly set.
|
||||
private predicate setsBodyAndStaticContentType(
|
||||
string package, string receiverName, DataFlow::Node bodyNode, string contentTypeString,
|
||||
DataFlow::Node receiverNode
|
||||
) {
|
||||
exists(string methodName, Method met, DataFlow::CallNode bodySetterCall |
|
||||
met.hasQualifiedName(package, receiverName, methodName) and
|
||||
bodySetterCall = met.getACall() and
|
||||
receiverNode = bodySetterCall.getReceiver()
|
||||
|
|
||||
package = packagePath() and
|
||||
(
|
||||
// Receiver type: Context
|
||||
receiverName = "Context" and
|
||||
(
|
||||
// signature: func (*Context).Error(code int, msg string) error
|
||||
methodName = "Error" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).HTML(code int, html string) error
|
||||
methodName = "HTML" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "text/html"
|
||||
or
|
||||
// signature: func (*Context).HTMLBlob(code int, bs []byte) error
|
||||
methodName = "HTMLBlob" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "text/html"
|
||||
or
|
||||
// signature: func (*Context).JSON(code int, data interface{}) error
|
||||
methodName = "JSON" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "application/json"
|
||||
or
|
||||
// signature: func (*Context).JSONBlob(code int, bs []byte) error
|
||||
methodName = "JSONBlob" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "application/json"
|
||||
or
|
||||
// signature: func (*Context).JSONP(code int, data interface{}) error
|
||||
methodName = "JSONP" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).JSONPBlob(code int, bs []byte) error
|
||||
methodName = "JSONPBlob" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).JSONPCallback(code int, callback string, data interface{}) error
|
||||
methodName = "JSONPCallback" and
|
||||
bodyNode = bodySetterCall.getArgument(2) and
|
||||
contentTypeString = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).JSONPCallbackBlob(code int, callback string, bs []byte) (err error)
|
||||
methodName = "JSONPCallbackBlob" and
|
||||
bodyNode = bodySetterCall.getArgument(2) and
|
||||
contentTypeString = "application/javascript"
|
||||
or
|
||||
// signature: func (*Context).String(code int, s string) error
|
||||
methodName = "String" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).StringBlob(code int, bs []byte) error
|
||||
methodName = "StringBlob" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).Stringf(code int, format string, a ...interface{}) error
|
||||
methodName = "Stringf" and
|
||||
bodyNode = bodySetterCall.getArgument([1, any(int i | i >= 2)]) and
|
||||
contentTypeString = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).XML(code int, data interface{}) error
|
||||
methodName = "XML" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "text/xml"
|
||||
or
|
||||
// signature: func (*Context).XMLBlob(code int, bs []byte) error
|
||||
methodName = "XMLBlob" and
|
||||
bodyNode = bodySetterCall.getArgument(1) and
|
||||
contentTypeString = "text/xml"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Models a HTTP header writer model for package: clevergo.tech/clevergo@v0.5.2
|
||||
* Models HTTP ResponseBody where the content-type can be dynamically set by the caller.
|
||||
*/
|
||||
private class HeaderWrite extends HTTP::HeaderWrite::Range, DataFlow::CallNode {
|
||||
HeaderWrite() {
|
||||
// Receiver type: Context
|
||||
// signature: func (*Context).SetHeader(key string, value string)
|
||||
this = any(Method m | m.hasQualifiedName(packagePath(), "Context", "SetHeader")).getACall()
|
||||
private class HttpResponseBodyDynamicContentType extends HTTP::ResponseBody::Range {
|
||||
DataFlow::Node contentTypeNode;
|
||||
DataFlow::Node receiverNode;
|
||||
|
||||
HttpResponseBodyDynamicContentType() {
|
||||
exists(string package, string receiverName |
|
||||
setsBodyAndDynamicContentType(package, receiverName, this, contentTypeNode, receiverNode)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getName() { result = this.getArgument(0) }
|
||||
override DataFlow::Node getAContentTypeNode() { result = contentTypeNode }
|
||||
|
||||
override DataFlow::Node getValue() { result = this.getArgument(1) }
|
||||
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
|
||||
}
|
||||
|
||||
override HTTP::ResponseWriter getResponseWriter() { none() }
|
||||
// Holds for a call that sets the body; the content-type is a parameter.
|
||||
// Both body and content-type are parameters in the same func call.
|
||||
private predicate setsBodyAndDynamicContentType(
|
||||
string package, string receiverName, DataFlow::Node bodyNode, DataFlow::Node contentTypeNode,
|
||||
DataFlow::Node receiverNode
|
||||
) {
|
||||
exists(string methodName, Method met, DataFlow::CallNode bodySetterCall |
|
||||
met.hasQualifiedName(package, receiverName, methodName) and
|
||||
bodySetterCall = met.getACall() and
|
||||
receiverNode = bodySetterCall.getReceiver()
|
||||
|
|
||||
package = packagePath() and
|
||||
(
|
||||
// Receiver type: Context
|
||||
receiverName = "Context" and
|
||||
(
|
||||
// signature: func (*Context).Blob(code int, contentType string, bs []byte) (err error)
|
||||
methodName = "Blob" and
|
||||
bodyNode = bodySetterCall.getArgument(2) and
|
||||
contentTypeNode = bodySetterCall.getArgument(1)
|
||||
or
|
||||
// signature: func (*Context).Emit(code int, contentType string, body string) (err error)
|
||||
methodName = "Emit" and
|
||||
bodyNode = bodySetterCall.getArgument(2) and
|
||||
contentTypeNode = bodySetterCall.getArgument(1)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Models HTTP ResponseBody where only the body is set.
|
||||
*/
|
||||
private class HttpResponseBodyNoContentType extends HTTP::ResponseBody::Range {
|
||||
DataFlow::Node receiverNode;
|
||||
|
||||
HttpResponseBodyNoContentType() {
|
||||
exists(string package, string receiverName |
|
||||
setsBody(package, receiverName, receiverNode, this)
|
||||
)
|
||||
}
|
||||
|
||||
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
|
||||
}
|
||||
|
||||
// Holds for a call that sets the body. The content-type is not defined.
|
||||
private predicate setsBody(
|
||||
string package, string receiverName, DataFlow::Node receiverNode, DataFlow::Node bodyNode
|
||||
) {
|
||||
exists(string methodName, Method met, DataFlow::CallNode bodySetterCall |
|
||||
met.hasQualifiedName(package, receiverName, methodName) and
|
||||
bodySetterCall = met.getACall() and
|
||||
receiverNode = bodySetterCall.getReceiver()
|
||||
|
|
||||
package = packagePath() and
|
||||
(
|
||||
// Receiver type: Context
|
||||
receiverName = "Context" and
|
||||
(
|
||||
// signature: func (*Context).Write(data []byte) (int, error)
|
||||
methodName = "Write" and
|
||||
bodyNode = bodySetterCall.getArgument(0)
|
||||
or
|
||||
// signature: func (*Context).WriteString(data string) (int, error)
|
||||
methodName = "WriteString" and
|
||||
bodyNode = bodySetterCall.getArgument(0)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Models HTTP header writers.
|
||||
* The write is done with a call where you can set both the key and the value of the header.
|
||||
*/
|
||||
private class HeaderWrite extends HTTP::HeaderWrite::Range, DataFlow::CallNode {
|
||||
DataFlow::Node receiverNode;
|
||||
DataFlow::Node headerNameNode;
|
||||
DataFlow::Node headerValueNode;
|
||||
|
||||
HeaderWrite() {
|
||||
setsHeaderDynamicKeyValue(_, _, this, headerNameNode, headerValueNode, receiverNode)
|
||||
}
|
||||
|
||||
override DataFlow::Node getName() { result = headerNameNode }
|
||||
|
||||
override DataFlow::Node getValue() { result = headerValueNode }
|
||||
|
||||
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
|
||||
}
|
||||
|
||||
// Holds for a call that sets a header with a key-value combination.
|
||||
private predicate setsHeaderDynamicKeyValue(
|
||||
string package, string receiverName, DataFlow::CallNode headerSetterCall,
|
||||
DataFlow::Node headerNameNode, DataFlow::Node headerValueNode, DataFlow::Node receiverNode
|
||||
) {
|
||||
exists(string methodName, Method met |
|
||||
met.hasQualifiedName(package, receiverName, methodName) and
|
||||
headerSetterCall = met.getACall() and
|
||||
receiverNode = headerSetterCall.getReceiver()
|
||||
|
|
||||
package = packagePath() and
|
||||
(
|
||||
// Receiver type: Context
|
||||
receiverName = "Context" and
|
||||
(
|
||||
// signature: func (*Context).SetHeader(key string, value string)
|
||||
methodName = "SetHeader" and
|
||||
headerNameNode = headerSetterCall.getArgument(0) and
|
||||
headerValueNode = headerSetterCall.getArgument(1)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Models an HTTP static content-type setter.
|
||||
*/
|
||||
private class StaticContentTypeSetter extends HTTP::HeaderWrite::Range, DataFlow::CallNode {
|
||||
DataFlow::Node receiverNode;
|
||||
string contentTypeString;
|
||||
|
||||
StaticContentTypeSetter() { setsStaticContentType(_, _, this, contentTypeString, receiverNode) }
|
||||
|
||||
override string getHeaderName() { result = "content-type" }
|
||||
|
||||
override string getHeaderValue() { result = contentTypeString }
|
||||
|
||||
override DataFlow::Node getName() { none() }
|
||||
|
||||
override DataFlow::Node getValue() { none() }
|
||||
|
||||
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
|
||||
}
|
||||
|
||||
// Holds for a call that sets the content-type (implicit).
|
||||
private predicate setsStaticContentType(
|
||||
string package, string receiverName, DataFlow::CallNode contentTypeSetterCall,
|
||||
string contentTypeString, DataFlow::Node receiverNode
|
||||
) {
|
||||
exists(string methodName, Method met |
|
||||
met.hasQualifiedName(package, receiverName, methodName) and
|
||||
contentTypeSetterCall = met.getACall() and
|
||||
receiverNode = contentTypeSetterCall.getReceiver()
|
||||
|
|
||||
package = packagePath() and
|
||||
(
|
||||
// Receiver type: Context
|
||||
receiverName = "Context" and
|
||||
(
|
||||
// signature: func (*Context).SetContentTypeHTML()
|
||||
methodName = "SetContentTypeHTML" and
|
||||
contentTypeString = "text/html"
|
||||
or
|
||||
// signature: func (*Context).SetContentTypeJSON()
|
||||
methodName = "SetContentTypeJSON" and
|
||||
contentTypeString = "application/json"
|
||||
or
|
||||
// signature: func (*Context).SetContentTypeText()
|
||||
methodName = "SetContentTypeText" and
|
||||
contentTypeString = "text/plain"
|
||||
or
|
||||
// signature: func (*Context).SetContentTypeXML()
|
||||
methodName = "SetContentTypeXML" and
|
||||
contentTypeString = "text/xml"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Models an HTTP dynamic content-type setter.
|
||||
*/
|
||||
private class DynamicContentTypeSetter extends HTTP::HeaderWrite::Range, DataFlow::CallNode {
|
||||
DataFlow::Node receiverNode;
|
||||
DataFlow::Node contentTypeNode;
|
||||
|
||||
DynamicContentTypeSetter() { setsDynamicContentType(_, _, this, contentTypeNode, receiverNode) }
|
||||
|
||||
override string getHeaderName() { result = "content-type" }
|
||||
|
||||
override DataFlow::Node getName() { none() }
|
||||
|
||||
override DataFlow::Node getValue() { result = contentTypeNode }
|
||||
|
||||
override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode }
|
||||
}
|
||||
|
||||
// Holds for a call that sets the content-type via a parameter.
|
||||
private predicate setsDynamicContentType(
|
||||
string package, string receiverName, DataFlow::CallNode contentTypeSetterCall,
|
||||
DataFlow::Node contentTypeNode, DataFlow::Node receiverNode
|
||||
) {
|
||||
exists(string methodName, Method met |
|
||||
met.hasQualifiedName(package, receiverName, methodName) and
|
||||
contentTypeSetterCall = met.getACall() and
|
||||
receiverNode = contentTypeSetterCall.getReceiver()
|
||||
|
|
||||
package = packagePath() and
|
||||
(
|
||||
// Receiver type: Context
|
||||
receiverName = "Context" and
|
||||
(
|
||||
// signature: func (*Context).SetContentType(v string)
|
||||
methodName = "SetContentType" and
|
||||
contentTypeNode = contentTypeSetterCall.getArgument(0)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,14 @@ module HTTP {
|
||||
abstract ResponseWriter getResponseWriter();
|
||||
|
||||
/** Gets a content-type associated with this body. */
|
||||
string getAContentType() { result = getAContentTypeNode().getStringValue() }
|
||||
string getAContentType() {
|
||||
exists(HTTP::HeaderWrite hw | hw = getResponseWriter().getAHeaderWrite() |
|
||||
hw.getHeaderName() = "content-type" and
|
||||
result = hw.getHeaderValue()
|
||||
)
|
||||
or
|
||||
result = getAContentTypeNode().getStringValue()
|
||||
}
|
||||
|
||||
/** Gets a dataflow node for a content-type associated with this body. */
|
||||
DataFlow::Node getAContentTypeNode() {
|
||||
|
||||
@@ -5,17 +5,55 @@ package main
|
||||
import "clevergo.tech/clevergo"
|
||||
|
||||
// Package clevergo.tech/clevergo@v0.5.2
|
||||
func HeaderWrite_ClevergoTechClevergov052() {
|
||||
func HeaderWrite_ClevergoTechClevergoV052() {
|
||||
// Header write via method calls.
|
||||
{
|
||||
// Header write via method calls on clevergo.tech/clevergo.Context.
|
||||
{
|
||||
// func (*Context).SetHeader(key string, value string)
|
||||
{
|
||||
keyString566 := source().(string)
|
||||
valString497 := source().(string)
|
||||
keyString506 := source().(string)
|
||||
valString213 := source().(string)
|
||||
var rece clevergo.Context
|
||||
rece.SetHeader(keyString566, valString497) // $headerKey=keyString566 $headerVal=valString497
|
||||
rece.SetHeader(keyString506, valString213) // $headerKeyNode=keyString506 $headerValNode=valString213
|
||||
}
|
||||
}
|
||||
}
|
||||
// Dynamic Content-Type header via method calls.
|
||||
{
|
||||
// Dynamic Content-Type header via method calls on clevergo.tech/clevergo.Context.
|
||||
{
|
||||
// func (*Context).SetContentType(v string)
|
||||
{
|
||||
valString468 := source().(string)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentType(valString468) // $headerKey=content-type $headerValNode=valString468
|
||||
}
|
||||
}
|
||||
}
|
||||
// Static Content-Type header write via method calls.
|
||||
{
|
||||
// Static Content-Type header write via method calls on clevergo.tech/clevergo.Context.
|
||||
{
|
||||
// func (*Context).SetContentTypeHTML()
|
||||
{
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeHTML() // $headerKey=content-type $headerVal=text/html
|
||||
}
|
||||
// func (*Context).SetContentTypeJSON()
|
||||
{
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeJSON() // $headerKey=content-type $headerVal=application/json
|
||||
}
|
||||
// func (*Context).SetContentTypeText()
|
||||
{
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeText() // $headerKey=content-type $headerVal=text/plain
|
||||
}
|
||||
// func (*Context).SetContentTypeXML()
|
||||
{
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeXML() // $headerKey=content-type $headerVal=text/xml
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,53 @@
|
||||
import go
|
||||
import experimental.frameworks.CleverGo
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import experimental.frameworks.CleverGo
|
||||
|
||||
class HttpHeaderWriteTest extends InlineExpectationsTest {
|
||||
HttpHeaderWriteTest() { this = "HttpHeaderWriteTest" }
|
||||
|
||||
override string getARelevantTag() { result = ["headerKey", "headerVal"] }
|
||||
override string getARelevantTag() {
|
||||
result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"]
|
||||
}
|
||||
|
||||
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
|
||||
// Dynamic key-value header:
|
||||
exists(HTTP::HeaderWrite hw |
|
||||
hw.hasLocationInfo(file, line, _, _, _) and
|
||||
(
|
||||
element = hw.getName().toString() and
|
||||
value = hw.getName().toString() and
|
||||
tag = "headerKeyNode"
|
||||
or
|
||||
element = hw.getValue().toString() and
|
||||
value = hw.getValue().toString() and
|
||||
tag = "headerValNode"
|
||||
)
|
||||
)
|
||||
or
|
||||
// Static key, dynamic value header:
|
||||
exists(HTTP::HeaderWrite hw |
|
||||
hw.hasLocationInfo(file, line, _, _, _) and
|
||||
(
|
||||
element = hw.getHeaderName().toString() and
|
||||
value = hw.getHeaderName() and
|
||||
tag = "headerKey"
|
||||
or
|
||||
element = hw.getValue().toString() and
|
||||
value = hw.getValue().toString() and
|
||||
tag = "headerValNode"
|
||||
)
|
||||
)
|
||||
or
|
||||
// Static key, static value header:
|
||||
exists(HTTP::HeaderWrite hw |
|
||||
hw.hasLocationInfo(file, line, _, _, _) and
|
||||
(
|
||||
element = hw.getHeaderName().toString() and
|
||||
value = hw.getHeaderName() and
|
||||
tag = "headerKey"
|
||||
or
|
||||
element = hw.getHeaderValue().toString() and
|
||||
value = hw.getHeaderValue() and
|
||||
tag = "headerVal"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ package main
|
||||
import "clevergo.tech/clevergo"
|
||||
|
||||
// Package clevergo.tech/clevergo@v0.5.2
|
||||
func HttpRedirect_ClevergoTechClevergov052() {
|
||||
func HttpRedirect_ClevergoTechClevergoV052() {
|
||||
// Redirect via method calls.
|
||||
{
|
||||
// Redirect via method calls on clevergo.tech/clevergo.Context.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import go
|
||||
import experimental.frameworks.CleverGo
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import experimental.frameworks.CleverGo
|
||||
|
||||
class HttpRedirectTest extends InlineExpectationsTest {
|
||||
HttpRedirectTest() { this = "HttpRedirectTest" }
|
||||
|
||||
@@ -5,7 +5,7 @@ package main
|
||||
import "clevergo.tech/clevergo"
|
||||
|
||||
// Package clevergo.tech/clevergo@v0.5.2
|
||||
func HttpResponseBody_ClevergoTechClevergov052() {
|
||||
func HttpResponseBody_ClevergoTechClevergoV052() {
|
||||
// Response body is set via a method call (the content-type is implicit in the method name).
|
||||
{
|
||||
// Response body is set via a method call on the clevergo.tech/clevergo.Context type (the content-type is implicit in the method name).
|
||||
@@ -115,71 +115,21 @@ func HttpResponseBody_ClevergoTechClevergov052() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Response body and content-type are set via calls of different methods.
|
||||
// Response body is set via a call of a type method.
|
||||
{
|
||||
// Response body and content-type are set via calls of different methods on the clevergo.tech/clevergo.Context type.
|
||||
// Response body is set via a call of a method on the clevergo.tech/clevergo.Context type.
|
||||
{
|
||||
// func (*Context).Write(data []byte) (int, error)
|
||||
{
|
||||
bodyByte982 := source().([]byte)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentType("application/json")
|
||||
rece.Write(bodyByte982) // $contentType=application/json $responseBody=bodyByte982
|
||||
}
|
||||
{
|
||||
bodyByte458 := source().([]byte)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeHTML()
|
||||
rece.Write(bodyByte458) // $contentType=text/html $responseBody=bodyByte458
|
||||
}
|
||||
{
|
||||
bodyByte506 := source().([]byte)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeJSON()
|
||||
rece.Write(bodyByte506) // $contentType=application/json $responseBody=bodyByte506
|
||||
}
|
||||
{
|
||||
bodyByte213 := source().([]byte)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeText()
|
||||
rece.Write(bodyByte213) // $contentType=text/plain $responseBody=bodyByte213
|
||||
}
|
||||
{
|
||||
bodyByte468 := source().([]byte)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeXML()
|
||||
rece.Write(bodyByte468) // $contentType=text/xml $responseBody=bodyByte468
|
||||
rece.Write(bodyByte982) // $responseBody=bodyByte982
|
||||
}
|
||||
// func (*Context).WriteString(data string) (int, error)
|
||||
{
|
||||
bodyString219 := source().(string)
|
||||
bodyString458 := source().(string)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentType("application/json")
|
||||
rece.WriteString(bodyString219) // $contentType=application/json $responseBody=bodyString219
|
||||
}
|
||||
{
|
||||
bodyString265 := source().(string)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeHTML()
|
||||
rece.WriteString(bodyString265) // $contentType=text/html $responseBody=bodyString265
|
||||
}
|
||||
{
|
||||
bodyString971 := source().(string)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeJSON()
|
||||
rece.WriteString(bodyString971) // $contentType=application/json $responseBody=bodyString971
|
||||
}
|
||||
{
|
||||
bodyString320 := source().(string)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeText()
|
||||
rece.WriteString(bodyString320) // $contentType=text/plain $responseBody=bodyString320
|
||||
}
|
||||
{
|
||||
bodyString545 := source().(string)
|
||||
var rece clevergo.Context
|
||||
rece.SetContentTypeXML()
|
||||
rece.WriteString(bodyString545) // $contentType=text/xml $responseBody=bodyString545
|
||||
rece.WriteString(bodyString458) // $responseBody=bodyString458
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import go
|
||||
import experimental.frameworks.CleverGo
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import experimental.frameworks.CleverGo
|
||||
|
||||
class HttpResponseBodyTest extends InlineExpectationsTest {
|
||||
HttpResponseBodyTest() { this = "HttpResponseBodyTest" }
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
// Package clevergo.tech/clevergo@v0.5.2
|
||||
func TaintTracking_ClevergoTechClevergov052() {
|
||||
func TaintTracking_ClevergoTechClevergoV052() {
|
||||
// Taint-tracking through functions.
|
||||
{
|
||||
// func CleanPath(p string) string
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import go
|
||||
import experimental.frameworks.CleverGo
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import experimental.frameworks.CleverGo
|
||||
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "test-configuration" }
|
||||
|
||||
@@ -5,7 +5,7 @@ package main
|
||||
import "clevergo.tech/clevergo"
|
||||
|
||||
// Package clevergo.tech/clevergo@v0.5.2
|
||||
func UntrustedSources_ClevergoTechClevergov052() {
|
||||
func UntrustedSources_ClevergoTechClevergoV052() {
|
||||
// Untrusted flow sources from method calls.
|
||||
{
|
||||
// Untrusted flow sources from method calls on clevergo.tech/clevergo.Context.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import go
|
||||
import experimental.frameworks.CleverGo
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import experimental.frameworks.CleverGo
|
||||
|
||||
class UntrustedFlowSourceTest extends InlineExpectationsTest {
|
||||
UntrustedFlowSourceTest() { this = "UntrustedFlowSourceTest" }
|
||||
|
||||
Reference in New Issue
Block a user