@@ -202,6 +202,42 @@ private class RequireVariable extends Variable {
202202 */
203203private predicate moduleInFile ( Module m , File f ) { m .getFile ( ) = f }
204204
205+ private predicate isModuleModule ( DataFlow:: Node nd ) {
206+ exists ( ImportDeclaration imp |
207+ imp .getImportedPath ( ) .getValue ( ) = "module" and
208+ nd =
209+ [
210+ DataFlow:: destructuredModuleImportNode ( imp ) ,
211+ DataFlow:: valueNode ( imp .getASpecifier ( ) .( ImportNamespaceSpecifier ) )
212+ ]
213+ )
214+ or
215+ isModuleModule ( nd .getAPredecessor ( ) )
216+ }
217+
218+ private predicate isCreateRequire ( DataFlow:: Node nd ) {
219+ exists ( PropAccess prop |
220+ isModuleModule ( prop .getBase ( ) .flow ( ) ) and
221+ prop .getPropertyName ( ) = "createRequire" and
222+ nd = prop .flow ( )
223+ )
224+ or
225+ exists ( PropertyPattern prop |
226+ isModuleModule ( prop .getObjectPattern ( ) .flow ( ) ) and
227+ prop .getName ( ) = "createRequire" and
228+ nd = prop .getValuePattern ( ) .flow ( )
229+ )
230+ or
231+ exists ( ImportDeclaration decl , NamedImportSpecifier spec |
232+ decl .getImportedPath ( ) .getValue ( ) = "module" and
233+ spec = decl .getASpecifier ( ) and
234+ spec .getImportedName ( ) = "createRequire" and
235+ nd = spec .flow ( )
236+ )
237+ or
238+ isCreateRequire ( nd .getAPredecessor ( ) )
239+ }
240+
205241/**
206242 * Holds if `nd` may refer to `require`, either directly or modulo local data flow.
207243 */
@@ -215,16 +251,11 @@ private predicate isRequire(DataFlow::Node nd) {
215251 or
216252 // `import { createRequire } from 'module';`.
217253 // 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 ( )
254+ // negative recursion between `Import.getImportedModuleNode()` and `Import.getImportedModule()`, and
255+ // to avoid depending on `SourceNode` as this would make `SourceNode::Range` recursive.
256+ exists ( CallExpr call |
257+ isCreateRequire ( call .getCallee ( ) .flow ( ) ) and
258+ nd = call .flow ( )
228259 )
229260}
230261
0 commit comments