mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
JavaScript: Teach type trackers to track flow through one level of properties.
This commit is contained in:
@@ -6,86 +6,68 @@ string chainableMethod() {
|
||||
}
|
||||
|
||||
class ApiObject extends DataFlow::NewNode {
|
||||
ApiObject() {
|
||||
this = DataFlow::moduleImport("@test/myapi").getAnInstantiation()
|
||||
}
|
||||
ApiObject() { this = DataFlow::moduleImport("@test/myapi").getAnInstantiation() }
|
||||
|
||||
DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = this
|
||||
or
|
||||
t.start() and
|
||||
result = ref(_).getAMethodCall(chainableMethod())
|
||||
result = ref(DataFlow::TypeTracker::end()).getAMethodCall(chainableMethod())
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = ref(t2).track(t2, t)
|
||||
)
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() {
|
||||
result = ref(_)
|
||||
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
class Connection extends DataFlow::SourceNode {
|
||||
ApiObject api;
|
||||
|
||||
Connection() {
|
||||
this = api.ref().getAMethodCall("createConnection")
|
||||
}
|
||||
Connection() { this = api.ref().getAMethodCall("createConnection") }
|
||||
|
||||
DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = this
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = ref(t2).track(t2, t)
|
||||
)
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() {
|
||||
result = ref(_)
|
||||
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
|
||||
|
||||
DataFlow::SourceNode getACallbackNode(DataFlow::TypeBackTracker t) {
|
||||
t.start() and
|
||||
result = ref().getAMethodCall("getData").getArgument(0).getALocalSource()
|
||||
or
|
||||
exists(DataFlow::TypeBackTracker t2 |
|
||||
result = getACallbackNode(t2).backtrack(t2, t)
|
||||
)
|
||||
exists(DataFlow::TypeBackTracker t2 | result = getACallbackNode(t2).backtrack(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::FunctionNode getACallback() {
|
||||
result = getACallbackNode(_).getAFunctionValue()
|
||||
result = getACallbackNode(DataFlow::TypeBackTracker::end()).getAFunctionValue()
|
||||
}
|
||||
}
|
||||
|
||||
class DataValue extends DataFlow::SourceNode {
|
||||
Connection connection;
|
||||
|
||||
DataValue() {
|
||||
this = connection.getACallback().getParameter(0)
|
||||
}
|
||||
DataValue() { this = connection.getACallback().getParameter(0) }
|
||||
|
||||
DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = this
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = ref(t2).track(t2, t)
|
||||
)
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() {
|
||||
result = ref(_)
|
||||
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) }
|
||||
}
|
||||
|
||||
query DataFlow::SourceNode test_ApiObject() { result = any(ApiObject obj).ref() }
|
||||
|
||||
query DataFlow::SourceNode test_Connection() { result = any(Connection c).ref() }
|
||||
|
||||
query DataFlow::SourceNode test_DataCallback() { result = any(Connection c).getACallbackNode(_) }
|
||||
query DataFlow::SourceNode test_DataCallback() {
|
||||
result = any(Connection c).getACallbackNode(DataFlow::TypeBackTracker::end())
|
||||
}
|
||||
|
||||
query DataFlow::SourceNode test_DataValue() { result = any(DataValue v).ref() }
|
||||
|
||||
@@ -10,52 +10,38 @@ DataFlow::SourceNode apiObject(DataFlow::TypeTracker t) {
|
||||
result = DataFlow::moduleImport("@test/myapi").getAnInstantiation()
|
||||
or
|
||||
t.start() and
|
||||
result = apiObject(_).getAMethodCall(chainableMethod())
|
||||
result = apiObject(DataFlow::TypeTracker::end()).getAMethodCall(chainableMethod())
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = apiObject(t2).track(t2, t)
|
||||
)
|
||||
exists(DataFlow::TypeTracker t2 | result = apiObject(t2).track(t2, t))
|
||||
}
|
||||
|
||||
query DataFlow::SourceNode apiObject() {
|
||||
result = apiObject(_)
|
||||
}
|
||||
query DataFlow::SourceNode apiObject() { result = apiObject(DataFlow::TypeTracker::end()) }
|
||||
|
||||
query DataFlow::SourceNode connection(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = apiObject().getAMethodCall("createConnection")
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = connection(t2).track(t2, t)
|
||||
)
|
||||
exists(DataFlow::TypeTracker t2 | result = connection(t2).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::SourceNode connection() {
|
||||
result = connection(_)
|
||||
}
|
||||
DataFlow::SourceNode connection() { result = connection(DataFlow::TypeTracker::end()) }
|
||||
|
||||
DataFlow::SourceNode dataCallback(DataFlow::TypeBackTracker t) {
|
||||
t.start() and
|
||||
result = connection().getAMethodCall("getData").getArgument(0).getALocalSource()
|
||||
or
|
||||
exists(DataFlow::TypeBackTracker t2 |
|
||||
result = dataCallback(t2).backtrack(t2, t)
|
||||
)
|
||||
exists(DataFlow::TypeBackTracker t2 | result = dataCallback(t2).backtrack(t2, t))
|
||||
}
|
||||
|
||||
query DataFlow::SourceNode dataCallback() {
|
||||
result = dataCallback(_)
|
||||
result = dataCallback(DataFlow::TypeBackTracker::end())
|
||||
}
|
||||
|
||||
DataFlow::SourceNode dataValue(DataFlow::TypeTracker t) {
|
||||
t.start() and
|
||||
result = dataCallback().getAFunctionValue().getParameter(0)
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 |
|
||||
result = dataValue(t2).track(t2, t)
|
||||
)
|
||||
exists(DataFlow::TypeTracker t2 | result = dataValue(t2).track(t2, t))
|
||||
}
|
||||
|
||||
query DataFlow::SourceNode dataValue() {
|
||||
result = dataValue(_)
|
||||
}
|
||||
query DataFlow::SourceNode dataValue() { result = dataValue(DataFlow::TypeTracker::end()) }
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
| src/exported-handler.js:1:19:1:55 | functio ... res) {} |
|
||||
| src/exported-middleware-attacher-2.js:2:13:2:32 | function(req, res){} |
|
||||
| src/exported-middleware-attacher.js:2:13:2:32 | function(req, res){} |
|
||||
| src/handler-in-property.js:5:14:5:33 | function(req, res){} |
|
||||
| src/handler-in-property.js:12:18:12:37 | function(req, res){} |
|
||||
| src/middleware-attacher-getter.js:4:17:4:36 | function(req, res){} |
|
||||
| src/middleware-attacher-getter.js:19:19:19:38 | function(req, res){} |
|
||||
| src/middleware-attacher.js:3:13:3:32 | function(req, res){} |
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
| src/bound-handler.js:4:1:4:28 | functio ... res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
|
||||
| src/bound-handler.js:9:12:9:31 | function(req, res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
|
||||
| src/handler-in-property.js:5:14:5:33 | function(req, res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
|
||||
| src/handler-in-property.js:12:18:12:37 | function(req, res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
|
||||
| src/hapi.js:1:1:1:30 | functio ... t, h){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
|
||||
| src/iterated-handlers.js:4:2:4:22 | functio ... res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
|
||||
| src/middleware-attacher-getter.js:29:32:29:51 | function(req, res){} | A `RouteHandlerCandidate` that did not get promoted to `RouteHandler`, and it is not used in a `RouteSetupCandidate`. |
|
||||
|
||||
Reference in New Issue
Block a user