@@ -271,7 +271,8 @@ module API {
271271 this = Impl:: MkMethodAccessNode ( result ) or
272272 this = Impl:: MkBackwardNode ( result , _) or
273273 this = Impl:: MkForwardNode ( result , _) or
274- this = Impl:: MkSinkNode ( result )
274+ this = Impl:: MkSinkNode ( result ) or
275+ this = Impl:: MkNamespaceOfTypeNameNode ( result )
275276 }
276277
277278 /** Gets the location of this node. */
@@ -324,45 +325,6 @@ module API {
324325 }
325326 }
326327
327- /** A node representing a module/class object with epsilon edges to its descendents. */
328- private class ModuleNode extends Node , Impl:: MkModule {
329- string qualifiedModule ;
330- int n ;
331-
332- ModuleNode ( ) { this = Impl:: MkModule ( qualifiedModule , n ) }
333-
334- ModuleNode getNext ( ) { result = Impl:: MkModule ( qualifiedModule , n + 1 ) }
335-
336- ModuleNode getPred ( ) { result .getNext ( ) = this }
337-
338- string getComponent ( ) { result = qualifiedModule .splitAt ( "." , n ) }
339-
340- string getModule ( ) {
341- not exists ( this .getPred ( ) ) and
342- result = this .getComponent ( )
343- or
344- result = this .getPred ( ) .getModule ( ) + "." + this .getComponent ( )
345- }
346-
347- override string toString ( ) { result = "Module(" + this .getModule ( ) + ")" }
348- }
349-
350- /** A node representing instances of a module/class with epsilon edges to its ancestors. */
351- private class InstanceUp extends Node , Impl:: MkInstanceUp {
352- /** Gets the module whose instances are represented by this API node. */
353- string getType ( ) { this = Impl:: MkInstanceUp ( result ) }
354-
355- override string toString ( ) { result = "ModuleInstanceUp(" + this .getType ( ) + ")" }
356- }
357-
358- /** A node representing instances of a module/class with epsilon edges to its descendents. */
359- private class InstanceDownNode extends Node , Impl:: MkInstanceDown {
360- /** Gets the module whose instances are represented by this API node. */
361- string getType ( ) { this = Impl:: MkInstanceDown ( result ) }
362-
363- override string toString ( ) { result = "ModuleInstanceDown(" + this .getType ( ) + ")" }
364- }
365-
366328 /** A node corresponding to the method being invoked at a method call. */
367329 class MethodAccessNode extends Node , Impl:: MkMethodAccessNode {
368330 override string toString ( ) { result = "MethodAccessNode(" + this .asCall ( ) + ")" }
@@ -378,6 +340,22 @@ module API {
378340 override string toString ( ) { result = "SinkNode(" + this .getInducingNode ( ) + ")" }
379341 }
380342
343+ private class UsingNode extends Node , Impl:: MkUsingNode {
344+ UsingStmt using ; // TODO: This should really be the cfg node, I think
345+
346+ UsingNode ( ) { this = Impl:: MkUsingNode ( using ) }
347+
348+ override string toString ( ) { result = "UsingNode(" + using + ")" }
349+ }
350+
351+ private class NamespaceOfTypeNameNode extends Node , Impl:: MkNamespaceOfTypeNameNode {
352+ DataFlow:: QualifiedTypeNameNode typeName ;
353+
354+ NamespaceOfTypeNameNode ( ) { this = Impl:: MkNamespaceOfTypeNameNode ( typeName ) }
355+
356+ override string toString ( ) { result = "NamespaceOfTypeNameNode(" + typeName + ")" }
357+ }
358+
381359 /**
382360 * An API entry point.
383361 *
@@ -415,11 +393,15 @@ module API {
415393 /** Gets the root node. */
416394 Node root ( ) { result instanceof RootNode }
417395
418- /**
419- * Gets the node that represents the module with qualified
420- * name `qualifiedModule`.
421- */
422- ModuleNode mod ( string qualifiedModule , int n ) { result = Impl:: MkModule ( qualifiedModule , n ) }
396+ bindingset [ name]
397+ pragma [ inline_late]
398+ Node namespace ( string name ) {
399+ // This predicate is currently not 'inline_late' because 'n' can be an input or output
400+ Impl:: namespace ( name , result )
401+ }
402+
403+ pragma [ inline]
404+ Node getTopLevelMember ( string name ) { Impl:: topLevelMember ( name , result ) }
423405
424406 /**
425407 * Gets an unqualified call at the top-level with the given method name.
@@ -466,44 +448,14 @@ module API {
466448
467449 cached
468450 private module Impl {
469- private predicate isGacModule ( string s ) {
470- s =
471- [
472- "System.Management.Automation" ,
473- "Microsoft.Management.Infrastructure" ,
474- "Microsoft.PowerShell.Security" ,
475- "Microsoft.PowerShell.Commands.Management" ,
476- "Microsoft.PowerShell.Commands.Utility"
477- ]
478- }
479-
480- private predicate isModule ( string s , int n ) {
481- (
482- any ( UsingStmt using ) .getName ( ) = s
483- or
484- any ( Cmd cmd ) .getNamespaceQualifier ( ) = s
485- or
486- any ( TypeNameExpr tn ) .getName ( ) = s
487- or
488- any ( ModuleManifest manifest ) .getModuleName ( ) = s
489- or
490- isGacModule ( s )
491- ) and
492- exists ( s .splitAt ( "." , n ) )
493- }
494-
495451 cached
496452 newtype TApiNode =
497453 /** The root of the API graph. */
498454 MkRoot ( ) or
499455 /** The method accessed at `call`, synthetically treated as a separate object. */
500456 MkMethodAccessNode ( DataFlow:: CallNode call ) or
501- MkModule ( string qualifiedModule , int n ) { isModule ( qualifiedModule , n ) } or
502- /** Instances of `mod` with epsilon edges to its ancestors. */
503- MkInstanceUp ( string qualifiedType ) { exists ( MkModule ( qualifiedType , _) ) } or
504- /** Instances of `mod` with epsilon edges to its descendents, and to its upward node. */
505- MkInstanceDown ( string qualifiedType ) { exists ( MkModule ( qualifiedType , _) ) } or
506- /** Intermediate node for following forward data flow. */
457+ MkUsingNode ( UsingStmt using ) or
458+ MkNamespaceOfTypeNameNode ( DataFlow:: QualifiedTypeNameNode typeName ) or
507459 MkForwardNode ( DataFlow:: LocalSourceNode node , TypeTracker t ) { isReachable ( node , t ) } or
508460 /** Intermediate node for following backward data flow. */
509461 MkBackwardNode ( DataFlow:: LocalSourceNode node , TypeTracker t ) { isReachable ( node , t ) } or
@@ -523,10 +475,30 @@ module API {
523475 pragma [ inline_late]
524476 private DataFlow:: Node getNodeFromExpr ( Expr e ) { result .asExpr ( ) .getExpr ( ) = e }
525477
478+ private import frameworks.data.ModelsAsData
479+
480+ cached
481+ predicate namespace ( string name , Node node ) {
482+ exists ( DataFlow:: QualifiedTypeNameNode typeName |
483+ typeName .getNamespace ( ) = name and
484+ node = MkNamespaceOfTypeNameNode ( typeName )
485+ )
486+ or
487+ exists ( UsingStmt using |
488+ using .getName ( ) .toLowerCase ( ) = name and
489+ node = MkUsingNode ( using )
490+ )
491+ or
492+ node = ModelOutput:: getATypeNode ( name )
493+ }
494+
495+ cached
496+ predicate topLevelMember ( string name , Node node ) { memberEdge ( root ( ) , name , node ) }
497+
526498 cached
527499 predicate toplevelCall ( string name , Node node ) {
528500 exists ( DataFlow:: CallNode call |
529- call .asExpr ( ) .getExpr ( ) .getEnclosingScope ( ) instanceof TopLevel and
501+ call .asExpr ( ) .getExpr ( ) .getEnclosingScope ( ) instanceof TopLevelScriptBlock and
530502 call .getName ( ) = name and
531503 node = MkMethodAccessNode ( call )
532504 )
@@ -544,26 +516,25 @@ module API {
544516
545517 cached
546518 predicate memberEdge ( Node pred , string name , Node succ ) {
547- exists ( MemberExpr member | succ = getForwardStartNode ( getNodeFromExpr ( member ) ) |
548- pred = getForwardEndNode ( getALocalSourceStrict ( getNodeFromExpr ( member .getQualifier ( ) ) ) ) and
549- name = member .getMemberName ( )
519+ exists ( StringConstExpr read |
520+ succ = getForwardStartNode ( getNodeFromExpr ( read ) ) and
521+ pred = MkRoot ( ) and
522+ name = read .getValueString ( )
523+ )
524+ or
525+ exists ( DataFlow:: QualifiedTypeNameNode typeName |
526+ typeName .getName ( ) = name and
527+ pred = MkNamespaceOfTypeNameNode ( typeName ) and
528+ succ = getForwardStartNode ( typeName )
550529 )
530+ // or
531+ // TODO: Handle getAMember when the predecessor is a MkUsingNode?
551532 }
552533
553534 cached
554535 predicate methodEdge ( Node pred , string name , Node succ ) {
555536 exists ( DataFlow:: CallNode call | succ = MkMethodAccessNode ( call ) and name = call .getName ( ) |
556537 pred = getForwardEndNode ( getALocalSourceStrict ( call .getQualifier ( ) ) )
557- or
558- exists ( string qualifiedModule , ModuleManifest manifest , int n |
559- pred = mod ( qualifiedModule , n ) and
560- not exists ( mod ( qualifiedModule , n + 1 ) ) and
561- manifest .getModuleName ( ) = qualifiedModule
562- |
563- manifest .getACmdLetToExport ( ) = name
564- or
565- manifest .getAFunctionToExport ( ) = name
566- )
567538 )
568539 }
569540
@@ -657,24 +628,10 @@ module API {
657628
658629 cached
659630 predicate instanceEdge ( Node pred , Node succ ) {
660- exists ( string qualifiedType , int n |
661- pred = MkModule ( qualifiedType , n ) and
662- not exists ( MkModule ( qualifiedType , n + 1 ) )
663- |
664- exists ( DataFlow:: TypeNameNode typeName |
665- typeName .getTypeName ( ) = qualifiedType and
666- succ = getForwardStartNode ( typeName )
667- )
668- or
669- exists ( DataFlow:: ObjectCreationNode objCreation |
670- objCreation .getConstructedTypeName ( ) = qualifiedType and
671- succ = getForwardStartNode ( objCreation )
672- )
673- or
674- exists ( DataFlow:: ParameterNode p |
675- p .getParameter ( ) .getStaticType ( ) = qualifiedType and
676- succ = getForwardStartNode ( p )
677- )
631+ // TODO: Also model parameters with a given type here
632+ exists ( DataFlow:: ObjectCreationNode objCreation |
633+ pred = getForwardEndNode ( objCreation .getConstructedTypeNode ( ) ) and
634+ succ = getForwardStartNode ( objCreation )
678635 )
679636 }
680637
0 commit comments