@@ -2533,6 +2533,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25332533 fwdFlow ( node , state , cc , summaryCtx , argT , argAp , t , ap , _) and
25342534 revFlow ( node , state , _, _, ap )
25352535 } or
2536+ TStagePathNodeSink ( NodeEx node , FlowState state ) {
2537+ exists ( StagePathNodeMid sink |
2538+ sink .isAtSink ( ) and
2539+ node = sink .getNodeEx ( ) and
2540+ state = sink .getState ( )
2541+ )
2542+ } or
25362543 TStagePathNodeSrcGrp ( ) or
25372544 TStagePathNodeSinkGrp ( )
25382545
@@ -2542,12 +2549,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25422549 /** Gets the `FlowState` of this node. */
25432550 abstract FlowState getState ( ) ;
25442551
2545- /** Gets a textual representation of this element . */
2546- abstract string toString ( ) ;
2552+ /** Holds if this node is a source . */
2553+ abstract predicate isSource ( ) ;
25472554
2548- predicate isSource ( ) { none ( ) }
2555+ /** Holds if this node is a sink. */
2556+ predicate isSink ( ) { this instanceof TStagePathNodeSink }
25492557
2550- predicate isSink ( ) { none ( ) }
2558+ abstract StagePathNodeImpl getASuccessorImpl ( string label ) ;
2559+
2560+ /** Gets a textual representation of this element. */
2561+ abstract string toString ( ) ;
25512562
25522563 /** Gets the location of this node. */
25532564 Location getLocation ( ) { result = this .getNodeEx ( ) .getLocation ( ) }
@@ -2565,6 +2576,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25652576 override NodeEx getNodeEx ( ) { none ( ) }
25662577
25672578 override FlowState getState ( ) { none ( ) }
2579+
2580+ override StagePathNodeImpl getASuccessorImpl ( string label ) {
2581+ result .isSource ( ) and label = ""
2582+ }
2583+
2584+ override predicate isSource ( ) { none ( ) }
25682585 }
25692586
25702587 private class StagePathNodeSinkGrp extends StagePathNodeImpl , TStagePathNodeSinkGrp {
@@ -2575,6 +2592,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25752592 override NodeEx getNodeEx ( ) { none ( ) }
25762593
25772594 override FlowState getState ( ) { none ( ) }
2595+
2596+ override StagePathNodeImpl getASuccessorImpl ( string label ) { none ( ) }
2597+
2598+ override predicate isSource ( ) { none ( ) }
25782599 }
25792600
25802601 /**
@@ -2599,6 +2620,48 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25992620
26002621 override FlowState getState ( ) { result = state }
26012622
2623+ private StagePathNodeMid getSuccMid ( string label ) {
2624+ localStep ( this , result , label )
2625+ or
2626+ nonLocalStep ( this , result , label )
2627+ }
2628+
2629+ private predicate isSourceWithLabel ( string labelprefix ) {
2630+ exists ( string model |
2631+ this .isSource ( ) and
2632+ sourceModel ( node , model ) and
2633+ model != "" and
2634+ labelprefix = "Src:" + model + " "
2635+ )
2636+ }
2637+
2638+ override StagePathNodeImpl getASuccessorImpl ( string label ) {
2639+ // an intermediate step to another intermediate node
2640+ exists ( string l2 | result = this .getSuccMid ( l2 ) |
2641+ not this .isSourceWithLabel ( _) and label = l2
2642+ or
2643+ exists ( string l1 |
2644+ this .isSourceWithLabel ( l1 ) and
2645+ label = l1 + l2
2646+ )
2647+ )
2648+ or
2649+ // a final step to a sink
2650+ exists ( string l2 , string sinkmodel |
2651+ result = this .getSuccMid ( l2 ) .projectToSink ( sinkmodel )
2652+ |
2653+ not this .isSourceWithLabel ( _) and
2654+ if sinkmodel != "" then label = l2 + " Sink:" + sinkmodel else label = l2
2655+ or
2656+ exists ( string l1 |
2657+ this .isSourceWithLabel ( l1 ) and
2658+ if sinkmodel != ""
2659+ then label = l1 + l2 + " Sink:" + sinkmodel
2660+ else label = l1 + l2
2661+ )
2662+ )
2663+ }
2664+
26022665 private string ppType ( ) {
26032666 exists ( string ppt | ppt = t .toString ( ) |
26042667 if ppt = "" then result = "" else result = " : " + ppt
@@ -2642,7 +2705,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
26422705 ap instanceof ApNil
26432706 }
26442707
2645- override predicate isSink ( ) {
2708+ predicate isAtSink ( ) {
26462709 sinkNode ( node , state ) and
26472710 ap instanceof ApNil and
26482711 // For `FeatureHasSinkCallContext` the condition `cc instanceof CallContextNoCall`
@@ -2662,6 +2725,37 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
26622725 then instanceofCcNoCall ( cc )
26632726 else any ( )
26642727 }
2728+
2729+ StagePathNodeSink projectToSink ( string model ) {
2730+ this .isAtSink ( ) and
2731+ sinkModel ( node , model ) and
2732+ result .getNodeEx ( ) = node and
2733+ result .getState ( ) = state
2734+ }
2735+ }
2736+
2737+ /**
2738+ * A flow graph node corresponding to a sink. This is disjoint from the
2739+ * intermediate nodes in order to uniquely correspond to a given sink by
2740+ * excluding the call context.
2741+ */
2742+ private class StagePathNodeSink extends StagePathNodeImpl , TStagePathNodeSink {
2743+ NodeEx node ;
2744+ FlowState state ;
2745+
2746+ StagePathNodeSink ( ) { this = TStagePathNodeSink ( node , state ) }
2747+
2748+ override NodeEx getNodeEx ( ) { result = node }
2749+
2750+ override FlowState getState ( ) { result = state }
2751+
2752+ override string toString ( ) { result = node .toString ( ) }
2753+
2754+ override StagePathNodeImpl getASuccessorImpl ( string label ) {
2755+ result .isArbitrarySink ( ) and label = ""
2756+ }
2757+
2758+ override predicate isSource ( ) { sourceNode ( node , state ) }
26652759 }
26662760
26672761 pragma [ nomagic]
@@ -2795,7 +2889,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
27952889 ) {
27962890 pn1 = pn2 and
27972891 summaryLabel = "" and
2798- subpaths ( _, pn1 , _, _)
2892+ subpathsImpl ( _, pn1 , _, _)
27992893 or
28002894 exists ( StagePathNodeImpl mid , string l1 , string l2 |
28012895 summaryLabel ( pn1 , mid , l1 ) and
@@ -2806,7 +2900,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28062900
28072901 private predicate summaryStep ( StagePathNodeImpl arg , StagePathNodeImpl out , string label ) {
28082902 exists ( StagePathNodeImpl par , StagePathNodeImpl ret |
2809- subpaths ( arg , par , ret , out ) and
2903+ subpathsImpl ( arg , par , ret , out ) and
28102904 summaryLabel ( par , ret , label )
28112905 )
28122906 }
@@ -2881,30 +2975,37 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28812975 )
28822976 }
28832977
2884- query predicate subpaths (
2978+ /**
2979+ * Holds if `(arg, par, ret, out)` forms a subpath-tuple.
2980+ *
2981+ * All of the nodes may be hidden.
2982+ */
2983+ private predicate subpathsImpl (
28852984 StagePathNodeImpl arg , StagePathNodeImpl par , StagePathNodeImpl ret ,
28862985 StagePathNodeImpl out
28872986 ) {
28882987 exists (
28892988 NodeEx node , FlowState state , Cc cc , ParamNodeOption summaryCtx , TypOption argT ,
2890- ApOption argAp , Typ t0 , Ap ap
2989+ ApOption argAp , Typ t0 , Ap ap , StagePathNodeImpl out0
28912990 |
28922991 fwdFlowThroughStep2 ( arg , par , ret , node , cc , state , summaryCtx , argT , argAp , t0 , ap ) and
2893- out = typeStrengthenToStagePathNode ( node , state , cc , summaryCtx , argT , argAp , t0 , ap )
2992+ out0 = typeStrengthenToStagePathNode ( node , state , cc , summaryCtx , argT , argAp , t0 , ap )
2993+ |
2994+ out = out0 or out = out0 .( StagePathNodeMid ) .projectToSink ( _)
28942995 )
28952996 }
28962997
2897- query predicate edges ( StagePathNodeImpl pn1 , StagePathNodeImpl pn2 , string key , string val ) {
2898- key = "provenance" and
2899- (
2900- localStep ( pn1 , pn2 , val )
2901- or
2902- nonLocalStep ( pn1 , pn2 , val )
2903- or
2904- pn1 . isArbitrarySource ( ) and pn2 . isSource ( ) and val = ""
2905- or
2906- pn1 . isSink ( ) and pn2 . isArbitrarySink ( ) and val = ""
2907- )
2998+ module StagePathGraph {
2999+ predicate edges ( StagePathNodeImpl a , StagePathNodeImpl b , string key , string val ) {
3000+ a . getASuccessorImpl ( val ) = b and
3001+ key = "provenance"
3002+ }
3003+
3004+ query predicate nodes ( StagePathNodeImpl n , string key , string val ) {
3005+ key = "semmle.label" and val = n . toString ( )
3006+ }
3007+
3008+ query predicate subpaths = subpathsImpl / 4 ;
29083009 }
29093010 }
29103011
0 commit comments