@@ -419,11 +419,20 @@ module API {
419419 exists ( DataFlow:: Node def , DataFlow:: SourceNode pred |
420420 rhs ( base , def ) and pred = trackDefNode ( def )
421421 |
422+ // from `x` to a definition of `x.prop`
422423 exists ( DataFlow:: PropWrite pw | pw = pred .getAPropertyWrite ( ) |
423424 lbl = Label:: memberFromRef ( pw ) and
424425 rhs = pw .getRhs ( )
425426 )
426427 or
428+ // special case: from `require('m')` to an export of `prop` in `m`
429+ exists ( Import imp , Module m , string prop |
430+ pred = imp .getImportedModuleNode ( ) and
431+ m = imp .getImportedModule ( ) and
432+ lbl = Label:: member ( prop ) and
433+ rhs = m .getAnExportedValue ( prop )
434+ )
435+ or
427436 exists ( DataFlow:: FunctionNode fn | fn = pred |
428437 not fn .getFunction ( ) .isAsync ( ) and
429438 lbl = Label:: return ( ) and
@@ -561,15 +570,11 @@ module API {
561570 cached
562571 predicate use ( TApiNode nd , DataFlow:: Node ref ) {
563572 exists ( string m , Module mod | nd = MkModuleDef ( m ) and mod = importableModule ( m ) |
564- ref = DataFlow:: ssaDefinitionNode ( SSA:: implicitInit ( mod .( NodeModule ) .getModuleVariable ( ) ) )
565- or
566- ref = DataFlow:: parameterNode ( mod .( AmdModule ) .getDefine ( ) .getModuleParameter ( ) )
573+ ref .( ModuleAsSourceNode ) .getModule ( ) = mod
567574 )
568575 or
569576 exists ( string m , Module mod | nd = MkModuleExport ( m ) and mod = importableModule ( m ) |
570- ref = DataFlow:: ssaDefinitionNode ( SSA:: implicitInit ( mod .( NodeModule ) .getExportsVariable ( ) ) )
571- or
572- ref = DataFlow:: parameterNode ( mod .( AmdModule ) .getDefine ( ) .getExportsParameter ( ) )
577+ ref .( ExportsAsSourceNode ) .getModule ( ) = mod
573578 or
574579 exists ( DataFlow:: Node base | use ( MkModuleDef ( m ) , base ) |
575580 ref = trackUseNode ( base ) .getAPropertyRead ( "exports" )
@@ -640,6 +645,16 @@ module API {
640645 rhs ( _, nd ) and
641646 result = nd .getALocalSource ( )
642647 or
648+ // additional backwards step from `require('m')` to `exports` or `module.exports` in m
649+ exists ( Import imp | imp .getImportedModuleNode ( ) = trackDefNode ( nd , t .continue ( ) ) |
650+ result .( ExportsAsSourceNode ) .getModule ( ) = imp .getImportedModule ( )
651+ or
652+ exists ( ModuleAsSourceNode mod |
653+ mod .getModule ( ) = imp .getImportedModule ( ) and
654+ result = mod .( DataFlow:: SourceNode ) .getAPropertyRead ( "exports" )
655+ )
656+ )
657+ or
643658 exists ( DataFlow:: TypeBackTracker t2 | result = trackDefNode ( nd , t2 ) .backtrack ( t2 , t ) )
644659 }
645660
@@ -796,13 +811,31 @@ private module Label {
796811}
797812
798813/**
799- * A CommonJS `module` or `exports ` variable, considered as a source node.
814+ * A CommonJS/AMD `module` variable, considered as a source node.
800815 */
801- private class AdditionalSourceNode extends DataFlow:: SourceNode:: Range {
802- AdditionalSourceNode ( ) {
803- exists ( NodeModule m , Variable v |
804- v in [ m .getModuleVariable ( ) , m .getExportsVariable ( ) ] and
805- this = DataFlow:: ssaDefinitionNode ( SSA:: implicitInit ( v ) )
806- )
816+ private class ModuleAsSourceNode extends DataFlow:: SourceNode:: Range {
817+ Module m ;
818+
819+ ModuleAsSourceNode ( ) {
820+ this = DataFlow:: ssaDefinitionNode ( SSA:: implicitInit ( m .( NodeModule ) .getModuleVariable ( ) ) )
821+ or
822+ this = DataFlow:: parameterNode ( m .( AmdModule ) .getDefine ( ) .getModuleParameter ( ) )
823+ }
824+
825+ Module getModule ( ) { result = m }
826+ }
827+
828+ /**
829+ * A CommonJS/AMD `exports` variable, considered as a source node.
830+ */
831+ private class ExportsAsSourceNode extends DataFlow:: SourceNode:: Range {
832+ Module m ;
833+
834+ ExportsAsSourceNode ( ) {
835+ this = DataFlow:: ssaDefinitionNode ( SSA:: implicitInit ( m .( NodeModule ) .getExportsVariable ( ) ) )
836+ or
837+ this = DataFlow:: parameterNode ( m .( AmdModule ) .getDefine ( ) .getExportsParameter ( ) )
807838 }
839+
840+ Module getModule ( ) { result = m }
808841}
0 commit comments