@@ -2533,6 +2533,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2533
2533
fwdFlow ( node , state , cc , summaryCtx , argT , argAp , t , ap , _) and
2534
2534
revFlow ( node , state , _, _, ap )
2535
2535
} 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
2536
2543
TStagePathNodeSrcGrp ( ) or
2537
2544
TStagePathNodeSinkGrp ( )
2538
2545
@@ -2542,12 +2549,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2542
2549
/** Gets the `FlowState` of this node. */
2543
2550
abstract FlowState getState ( ) ;
2544
2551
2545
- /** Gets a textual representation of this element . */
2546
- abstract string toString ( ) ;
2552
+ /** Holds if this node is a source . */
2553
+ abstract predicate isSource ( ) ;
2547
2554
2548
- predicate isSource ( ) { none ( ) }
2555
+ /** Holds if this node is a sink. */
2556
+ predicate isSink ( ) { this instanceof TStagePathNodeSink }
2549
2557
2550
- predicate isSink ( ) { none ( ) }
2558
+ abstract StagePathNodeImpl getASuccessorImpl ( string label ) ;
2559
+
2560
+ /** Gets a textual representation of this element. */
2561
+ abstract string toString ( ) ;
2551
2562
2552
2563
/** Gets the location of this node. */
2553
2564
Location getLocation ( ) { result = this .getNodeEx ( ) .getLocation ( ) }
@@ -2565,6 +2576,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2565
2576
override NodeEx getNodeEx ( ) { none ( ) }
2566
2577
2567
2578
override FlowState getState ( ) { none ( ) }
2579
+
2580
+ override StagePathNodeImpl getASuccessorImpl ( string label ) {
2581
+ result .isSource ( ) and label = ""
2582
+ }
2583
+
2584
+ override predicate isSource ( ) { none ( ) }
2568
2585
}
2569
2586
2570
2587
private class StagePathNodeSinkGrp extends StagePathNodeImpl , TStagePathNodeSinkGrp {
@@ -2575,6 +2592,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2575
2592
override NodeEx getNodeEx ( ) { none ( ) }
2576
2593
2577
2594
override FlowState getState ( ) { none ( ) }
2595
+
2596
+ override StagePathNodeImpl getASuccessorImpl ( string label ) { none ( ) }
2597
+
2598
+ override predicate isSource ( ) { none ( ) }
2578
2599
}
2579
2600
2580
2601
/**
@@ -2599,6 +2620,48 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2599
2620
2600
2621
override FlowState getState ( ) { result = state }
2601
2622
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
+
2602
2665
private string ppType ( ) {
2603
2666
exists ( string ppt | ppt = t .toString ( ) |
2604
2667
if ppt = "" then result = "" else result = " : " + ppt
@@ -2642,7 +2705,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2642
2705
ap instanceof ApNil
2643
2706
}
2644
2707
2645
- override predicate isSink ( ) {
2708
+ predicate isAtSink ( ) {
2646
2709
sinkNode ( node , state ) and
2647
2710
ap instanceof ApNil and
2648
2711
// For `FeatureHasSinkCallContext` the condition `cc instanceof CallContextNoCall`
@@ -2662,6 +2725,37 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2662
2725
then instanceofCcNoCall ( cc )
2663
2726
else any ( )
2664
2727
}
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 ) }
2665
2759
}
2666
2760
2667
2761
pragma [ nomagic]
@@ -2795,7 +2889,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2795
2889
) {
2796
2890
pn1 = pn2 and
2797
2891
summaryLabel = "" and
2798
- subpaths ( _, pn1 , _, _)
2892
+ subpathsImpl ( _, pn1 , _, _)
2799
2893
or
2800
2894
exists ( StagePathNodeImpl mid , string l1 , string l2 |
2801
2895
summaryLabel ( pn1 , mid , l1 ) and
@@ -2806,7 +2900,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2806
2900
2807
2901
private predicate summaryStep ( StagePathNodeImpl arg , StagePathNodeImpl out , string label ) {
2808
2902
exists ( StagePathNodeImpl par , StagePathNodeImpl ret |
2809
- subpaths ( arg , par , ret , out ) and
2903
+ subpathsImpl ( arg , par , ret , out ) and
2810
2904
summaryLabel ( par , ret , label )
2811
2905
)
2812
2906
}
@@ -2881,30 +2975,37 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2881
2975
)
2882
2976
}
2883
2977
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 (
2885
2984
StagePathNodeImpl arg , StagePathNodeImpl par , StagePathNodeImpl ret ,
2886
2985
StagePathNodeImpl out
2887
2986
) {
2888
2987
exists (
2889
2988
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
2891
2990
|
2892
2991
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 ( _)
2894
2995
)
2895
2996
}
2896
2997
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 ;
2908
3009
}
2909
3010
}
2910
3011
0 commit comments