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