JavaScript: Teach type trackers to track flow through one level of properties.

This commit is contained in:
Max Schaefer
2019-03-21 10:16:57 +00:00
parent 9fbc0eb717
commit 084159dcfd
13 changed files with 128 additions and 92 deletions

View File

@@ -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() }

View File

@@ -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()) }

View File

@@ -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){} |

View File

@@ -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`. |