@@ -202,6 +202,34 @@ private class RequireVariable extends Variable {
202
202
*/
203
203
private predicate moduleInFile ( Module m , File f ) { m .getFile ( ) = f }
204
204
205
+ private predicate isModuleModule ( DataFlow:: Node nd ) {
206
+ exists ( ImportDeclaration imp |
207
+ imp .getImportedPath ( ) .getValue ( ) = "module" and
208
+ nd = [
209
+ DataFlow:: destructuredModuleImportNode ( imp ) ,
210
+ DataFlow:: valueNode ( imp .getASpecifier ( ) .( ImportNamespaceSpecifier ) )
211
+ ]
212
+ )
213
+ or
214
+ isModuleModule ( nd .getAPredecessor ( ) )
215
+ }
216
+
217
+ private predicate isCreateRequire ( DataFlow:: Node nd ) {
218
+ exists ( PropAccess prop |
219
+ isModuleModule ( prop .getBase ( ) .flow ( ) ) and
220
+ prop .getPropertyName ( ) = "createRequire" and
221
+ nd = prop .flow ( )
222
+ )
223
+ or
224
+ exists ( PropertyPattern prop |
225
+ isModuleModule ( prop .getObjectPattern ( ) .flow ( ) ) and
226
+ prop .getName ( ) = "createRequire" and
227
+ nd = prop .getValuePattern ( ) .flow ( )
228
+ )
229
+ or
230
+ isCreateRequire ( nd .getAPredecessor ( ) )
231
+ }
232
+
205
233
/**
206
234
* Holds if `nd` may refer to `require`, either directly or modulo local data flow.
207
235
*/
@@ -215,16 +243,11 @@ private predicate isRequire(DataFlow::Node nd) {
215
243
or
216
244
// `import { createRequire } from 'module';`.
217
245
// specialized to ES2015 modules to avoid recursion in the `DataFlow::moduleImport()` predicate and to avoid
218
- // negative recursion between `Import.getImportedModuleNode()` and `Import.getImportedModule()`.
219
- exists ( ImportDeclaration imp , DataFlow:: SourceNode baseObj |
220
- imp .getImportedPath ( ) .getValue ( ) = "module"
221
- |
222
- baseObj =
223
- [
224
- DataFlow:: destructuredModuleImportNode ( imp ) ,
225
- DataFlow:: valueNode ( imp .getASpecifier ( ) .( ImportNamespaceSpecifier ) )
226
- ] and
227
- nd = baseObj .getAPropertyRead ( "createRequire" ) .getACall ( )
246
+ // negative recursion between `Import.getImportedModuleNode()` and `Import.getImportedModule()`, and
247
+ // to avoid depending on `SourceNode` as this would make `SourceNode::Range` recursive.
248
+ exists ( CallExpr call |
249
+ isCreateRequire ( call .getCallee ( ) .flow ( ) ) and
250
+ nd = call .flow ( )
228
251
)
229
252
}
230
253
0 commit comments