88import javascript
99private import semmle.javascript.dataflow.internal.FlowSteps as FlowSteps
1010private import semmle.javascript.dataflow.internal.PreCallGraphStep
11+ private import semmle.javascript.dataflow.internal.StepSummary as StepSummary
1112private import semmle.javascript.dataflow.internal.sharedlib.SummaryTypeTracker as SummaryTypeTracker
1213private import internal.CachedStages
1314
@@ -1238,8 +1239,6 @@ module API {
12381239 t = useStep ( nd , promisified , boundArgs , prop , result )
12391240 }
12401241
1241- private import semmle.javascript.dataflow.internal.StepSummary
1242-
12431242 /**
12441243 * Holds if `nd`, which is a use of an API-graph node, flows in zero or more potentially
12451244 * inter-procedural steps to some intermediate node, and then from that intermediate node to
@@ -1251,9 +1250,9 @@ module API {
12511250 private DataFlow:: TypeTracker useStep (
12521251 DataFlow:: Node nd , boolean promisified , int boundArgs , string prop , DataFlow:: Node res
12531252 ) {
1254- exists ( DataFlow:: TypeTracker t , StepSummary summary , DataFlow:: SourceNode prev |
1253+ exists ( DataFlow:: TypeTracker t , StepSummary:: StepSummary summary , DataFlow:: SourceNode prev |
12551254 prev = trackUseNode ( nd , promisified , boundArgs , prop , t ) and
1256- StepSummary:: step ( prev , res , summary ) and
1255+ StepSummary:: StepSummary :: step ( prev , res , summary ) and
12571256 result = t .append ( summary )
12581257 )
12591258 }
@@ -1308,9 +1307,9 @@ module API {
13081307 */
13091308 pragma [ noopt]
13101309 private DataFlow:: TypeBackTracker defStep ( DataFlow:: Node nd , DataFlow:: SourceNode prev ) {
1311- exists ( DataFlow:: TypeBackTracker t , StepSummary summary , DataFlow:: Node next |
1310+ exists ( DataFlow:: TypeBackTracker t , StepSummary:: StepSummary summary , DataFlow:: Node next |
13121311 next = trackDefNode ( nd , t ) and
1313- StepSummary:: step ( prev , next , summary ) and
1312+ StepSummary:: StepSummary :: step ( prev , next , summary ) and
13141313 result = t .prepend ( summary )
13151314 )
13161315 }
@@ -1385,7 +1384,7 @@ module API {
13851384 or
13861385 exists ( string moduleName , string exportName |
13871386 pred = MkModuleImport ( moduleName ) and
1388- lbl = Label:: member ( exportName ) and
1387+ lbl = Label:: qualifiedTypeName ( exportName ) and
13891388 succ = MkTypeUse ( moduleName , exportName )
13901389 )
13911390 or
@@ -1495,7 +1494,11 @@ module API {
14951494 /** Gets the `member` edge label for member `m`. */
14961495 bindingset [ m]
14971496 bindingset [ result ]
1498- LabelContent member ( string m ) { result .getContent ( ) .asPropertyName ( ) = m }
1497+ LabelMember member ( string m ) { result .getProperty ( ) = m }
1498+
1499+ bindingset [ m]
1500+ bindingset [ result ]
1501+ LabelQualifiedName qualifiedTypeName ( string m ) { result .getName ( ) = m }
14991502
15001503 /** Gets the `content` edge label for content `c`. */
15011504 LabelContent content ( Content c ) { result .getContent ( ) = c }
@@ -1586,6 +1589,7 @@ module API {
15861589 } or
15871590 MkLabelInstance ( ) or
15881591 MkLabelContent ( DataFlow:: Content content ) or
1592+ MkLabelMember ( StepSummary:: PropertyName name ) or
15891593 MkLabelParameter ( int i ) {
15901594 i =
15911595 [ 0 .. max ( int args |
@@ -1594,6 +1598,11 @@ module API {
15941598 ) ] or
15951599 i = [ 0 .. 10 ]
15961600 } or
1601+ MkLabelQualifiedName ( string qname ) {
1602+ any ( DataFlow:: SourceNode sn ) .hasUnderlyingType ( qname )
1603+ or
1604+ any ( DataFlow:: SourceNode sn ) .hasUnderlyingType ( _, qname )
1605+ } or
15971606 MkLabelReceiver ( ) or
15981607 MkLabelReturn ( ) or
15991608 MkLabelDecoratedClass ( ) or
@@ -1651,27 +1660,53 @@ module API {
16511660 class LabelContent extends ApiLabel , MkLabelContent {
16521661 private DataFlow:: Content content ;
16531662
1654- LabelContent ( ) { this = MkLabelContent ( content ) }
1663+ LabelContent ( ) {
1664+ this = MkLabelContent ( content ) and
1665+ // Property names are represented by LabelMember to ensure additional property
1666+ // names from PreCallGraph step are included (which may not be included in Content).
1667+ not content instanceof MkPropertyContent
1668+ }
16551669
16561670 /** Gets the content associated with this label. */
16571671 DataFlow:: Content getContent ( ) { result = content }
16581672
1673+ private string specialisedToString ( ) {
1674+ content instanceof MkPromiseValue and result = "getPromised()"
1675+ or
1676+ content instanceof MkPromiseError and result = "getPromisedError()"
1677+ or
1678+ content instanceof MkArrayElementUnknown and result = "getUnknownMember()"
1679+ }
1680+
16591681 override string toString ( ) {
1660- result = "getMember(\"" + content . asPropertyName ( ) + "\")"
1682+ result = this . specialisedToString ( )
16611683 or
1662- not exists ( content . asPropertyName ( ) ) and
1684+ not exists ( this . specialisedToString ( ) ) and
16631685 result = "getContent(" + content + ")"
16641686 }
16651687 }
16661688
16671689 /** A label for the member named `prop`. */
1668- deprecated class LabelMember extends LabelContent {
1669- private string prop ;
1690+ class LabelMember extends ApiLabel , MkLabelMember {
1691+ private StepSummary :: PropertyName prop ;
16701692
1671- LabelMember ( ) { prop = this . getContent ( ) . asPropertyName ( ) }
1693+ LabelMember ( ) { this = MkLabelMember ( prop ) }
16721694
16731695 /** Gets the property associated with this label. */
16741696 string getProperty ( ) { result = prop }
1697+
1698+ override string toString ( ) { result = "getMember(\"" + prop + "\")" }
1699+ }
1700+
1701+ /** A label for the member named `prop`. */
1702+ class LabelQualifiedName extends ApiLabel , MkLabelQualifiedName {
1703+ private string prop ;
1704+
1705+ LabelQualifiedName ( ) { this = MkLabelQualifiedName ( prop ) }
1706+
1707+ string getName ( ) { result = prop }
1708+
1709+ override string toString ( ) { result = "getMember(\"" + prop + "\")" }
16751710 }
16761711
16771712 /** A label for a member with an unknown name. */
0 commit comments