Skip to content

Commit 95f21b5

Browse files
authored
Merge pull request #7027 from github/z80coder/faster-callee-api-name-feature
more efficient implementation of calleeApiName
2 parents 58f6058 + b8d7f52 commit 95f21b5

File tree

1 file changed

+35
-36
lines changed
  • javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling

1 file changed

+35
-36
lines changed

javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/EndpointFeatures.qll

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private string getTokenFeature(DataFlow::Node endpoint, string featureName) {
5656
result =
5757
concat(API::Node node, string accessPath |
5858
node.getInducingNode().(DataFlow::CallNode).getAnArgument() = endpoint and
59-
accessPath = AccessPaths::getAccessPath(node, includeStructuralInfo)
59+
AccessPaths::accessPaths(node, includeStructuralInfo, accessPath, _)
6060
|
6161
accessPath, " "
6262
)
@@ -102,7 +102,9 @@ private string getACallBasedTokenFeatureComponent(
102102
//
103103
// would have a callee API name of `mongoose`.
104104
featureName = "calleeApiName" and
105-
result = getAnApiName(call)
105+
exists(API::Node apiNode |
106+
AccessPaths::accessPaths(apiNode, false, _, result) and call = apiNode.getInducingNode()
107+
)
106108
)
107109
}
108110

@@ -145,16 +147,6 @@ module FunctionBodies {
145147
}
146148
}
147149

148-
/**
149-
* Returns a name of the API that a node originates from, if the node originates from an API.
150-
*
151-
* This predicate may have multiple results if the node corresponds to multiple nodes in the API graph forest.
152-
*/
153-
pragma[inline]
154-
private string getAnApiName(DataFlow::Node node) {
155-
API::moduleImport(result).getASuccessor*().getInducingNode() = node
156-
}
157-
158150
/**
159151
* This module provides functionality for getting a representation of the access path of nodes
160152
* within the program.
@@ -200,65 +192,72 @@ private module AccessPaths {
200192
}
201193

202194
/** Get the access path for the node. This includes structural information like `member`, `param`, and `functionalarg` if `includeStructuralInfo` is true. */
203-
string getAccessPath(API::Node node, Boolean includeStructuralInfo) {
204-
node = API::moduleImport(result)
195+
predicate accessPaths(
196+
API::Node node, Boolean includeStructuralInfo, string accessPath, string apiName
197+
) {
198+
//node = API::moduleImport(result)
199+
node = API::moduleImport(apiName) and accessPath = apiName
205200
or
206-
exists(API::Node base, string baseName |
207-
base.getDepth() < node.getDepth() and baseName = getAccessPath(base, includeStructuralInfo)
201+
exists(API::Node previousNode, string previousAccessPath |
202+
previousNode.getDepth() < node.getDepth() and
203+
accessPaths(previousNode, includeStructuralInfo, previousAccessPath, apiName)
208204
|
209205
// e.g. `new X`, `X()`
210-
node = [base.getInstance(), base.getReturn()] and
206+
node = [previousNode.getInstance(), previousNode.getReturn()] and
211207
if includeStructuralInfo = true
212-
then result = baseName + " instanceorreturn"
213-
else result = baseName
208+
then accessPath = previousAccessPath + " instanceorreturn"
209+
else accessPath = previousAccessPath
214210
or
215211
// e.g. `x.y`, `x[y]`, `const { y } = x`, where `y` is non-numeric and is known at analysis
216212
// time.
217213
exists(string member |
218-
node = base.getMember(member) and
219-
not node = base.getUnknownMember() and
214+
node = previousNode.getMember(member) and
215+
not node = previousNode.getUnknownMember() and
220216
not isNumericString(member) and
221-
not (member = "default" and base = API::moduleImport(_)) and
217+
not (member = "default" and previousNode = API::moduleImport(_)) and
222218
not member = "then" // use the 'promised' edges for .then callbacks
223219
|
224220
if includeStructuralInfo = true
225-
then result = baseName + " member " + member
226-
else result = baseName + " " + member
221+
then accessPath = previousAccessPath + " member " + member
222+
else accessPath = previousAccessPath + " " + member
227223
)
228224
or
229225
// e.g. `x.y`, `x[y]`, `const { y } = x`, where `y` is numeric or not known at analysis time.
230226
(
231-
node = base.getUnknownMember() or
232-
node = base.getMember(any(string s | isNumericString(s)))
227+
node = previousNode.getUnknownMember() or
228+
node = previousNode.getMember(any(string s | isNumericString(s)))
233229
) and
234-
if includeStructuralInfo = true then result = baseName + " member" else result = baseName
230+
if includeStructuralInfo = true
231+
then accessPath = previousAccessPath + " member"
232+
else accessPath = previousAccessPath
235233
or
236234
// e.g. `x.then(y => ...)`
237-
node = base.getPromised() and
238-
result = baseName
235+
node = previousNode.getPromised() and
236+
accessPath = previousAccessPath
239237
or
240238
// e.g. `x.y((a, b) => ...)`
241239
// Name callback parameters after their name in the source code.
242240
// For example, the `res` parameter in `express.get('/foo', (req, res) => {...})` will be
243241
// named `express member get functionalarg param res`.
244242
exists(string paramName |
245-
node = getNamedParameter(base.getAParameter(), paramName) and
243+
node = getNamedParameter(previousNode.getAParameter(), paramName) and
246244
(
247245
if includeStructuralInfo = true
248-
then result = baseName + " functionalarg param " + paramName
249-
else result = baseName + " " + paramName
246+
then accessPath = previousAccessPath + " functionalarg param " + paramName
247+
else accessPath = previousAccessPath + " " + paramName
250248
)
251249
or
252250
exists(string callbackName, string index |
253251
node =
254-
getNamedParameter(base.getASuccessor("param " + index).getMember(callbackName),
252+
getNamedParameter(previousNode.getASuccessor("param " + index).getMember(callbackName),
255253
paramName) and
256254
index != "-1" and // ignore receiver
257255
if includeStructuralInfo = true
258256
then
259-
result =
260-
baseName + " functionalarg " + index + " " + callbackName + " param " + paramName
261-
else result = baseName + " " + index + " " + callbackName + " " + paramName
257+
accessPath =
258+
previousAccessPath + " functionalarg " + index + " " + callbackName + " param " +
259+
paramName
260+
else accessPath = previousAccessPath + " " + index + " " + callbackName + " " + paramName
262261
)
263262
)
264263
)

0 commit comments

Comments
 (0)