@@ -152,6 +152,18 @@ private class RequireVariable extends Variable {
152152 */
153153private predicate moduleInFile ( Module m , File f ) { m .getFile ( ) = f }
154154
155+ /**
156+ * Holds if `nd` may refer to `require`, either directly or modulo local data flow.
157+ */
158+ cached
159+ private predicate isRequire ( DataFlow:: Node nd ) {
160+ nd .asExpr ( ) = any ( RequireVariable req ) .getAnAccess ( ) and
161+ // `mjs` files explicitly disallow `require`
162+ not nd .getFile ( ) .getExtension ( ) = "mjs"
163+ or
164+ isRequire ( nd .getAPredecessor ( ) )
165+ }
166+
155167/**
156168 * A `require` import.
157169 *
@@ -162,12 +174,7 @@ private predicate moduleInFile(Module m, File f) { m.getFile() = f }
162174 * ```
163175 */
164176class Require extends CallExpr , Import {
165- cached
166- Require ( ) {
167- any ( RequireVariable req ) .getAnAccess ( ) = getCallee ( ) and
168- // `mjs` files explicitly disallow `require`
169- not getFile ( ) .getExtension ( ) = "mjs"
170- }
177+ Require ( ) { isRequire ( getCallee ( ) .flow ( ) ) }
171178
172179 override PathExpr getImportedPath ( ) { result = getArgument ( 0 ) }
173180
@@ -257,8 +264,8 @@ private class RequirePath extends PathExprCandidate {
257264 RequirePath ( ) {
258265 this = any ( Require req ) .getArgument ( 0 )
259266 or
260- exists ( RequireVariable req , MethodCallExpr reqres |
261- reqres .getReceiver ( ) = req . getAnAccess ( ) and
267+ exists ( MethodCallExpr reqres |
268+ isRequire ( reqres .getReceiver ( ) . flow ( ) ) and
262269 reqres .getMethodName ( ) = "resolve" and
263270 this = reqres .getArgument ( 0 )
264271 )
0 commit comments