@@ -437,6 +437,9 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
437
437
* is not visualized (as it is in a `path-problem` query).
438
438
*/
439
439
default predicate includeHiddenNodes ( ) { none ( ) }
440
+ //
441
+ // If you add a predicate to ConfigSig, please also add a corresponding
442
+ // passthrough alias to FilteredConfig below.
440
443
}
441
444
442
445
/** An input configuration for data flow using flow state. */
@@ -559,6 +562,9 @@ module Configs<LocationSig Location, InputSig<Location> Lang> {
559
562
* is not visualized (as it is in a `path-problem` query).
560
563
*/
561
564
default predicate includeHiddenNodes ( ) { none ( ) }
565
+ //
566
+ // If you add a predicate to StateConfigSig, please also add a corresponding
567
+ // passthrough alias to FilteredStateConfig below.
562
568
}
563
569
}
564
570
@@ -835,4 +841,166 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
835
841
}
836
842
}
837
843
}
844
+
845
+ /**
846
+ * This wrapper applies alert filters to an existing `ConfigSig` module. It is intended to be used
847
+ * in the specific case where both the dataflow sources and the dataflow sinks are presented in
848
+ * the query result, so we need to apply the alert filter on either the source or the sink (which
849
+ * is what this wrapper does).
850
+ */
851
+ module FilteredConfig< ConfigSig Config> implements ConfigSig {
852
+ private import codeql.util.AlertFiltering
853
+
854
+ private module AlertFiltering = AlertFilteringImpl< Location > ;
855
+
856
+ pragma [ noinline]
857
+ private predicate hasFilteredSource ( ) {
858
+ exists ( Node n | Config:: isSource ( n ) | AlertFiltering:: filterByLocation ( n .getLocation ( ) ) )
859
+ }
860
+
861
+ pragma [ noinline]
862
+ private predicate hasFilteredSink ( ) {
863
+ exists ( Node n | Config:: isSink ( n ) | AlertFiltering:: filterByLocation ( n .getLocation ( ) ) )
864
+ }
865
+
866
+ predicate isSource ( Node source ) {
867
+ Config:: isSource ( source ) and
868
+ (
869
+ // If there are filtered sinks, we need to pass through all sources to preserve all alerts
870
+ // with filtered sinks. Otherwise the only alerts of interest are those with filtered
871
+ // sources, so we can perform the source filtering right here.
872
+ hasFilteredSink ( ) or
873
+ AlertFiltering:: filterByLocation ( source .getLocation ( ) )
874
+ )
875
+ }
876
+
877
+ predicate isSink ( Node sink ) {
878
+ Config:: isSink ( sink ) and
879
+ (
880
+ // If there are filtered sources, we need to pass through all sinks to preserve all alerts
881
+ // with filtered sources. Otherwise the only alerts of interest are those with filtered
882
+ // sinks, so we can perform the sink filtering right here.
883
+ hasFilteredSource ( ) or
884
+ AlertFiltering:: filterByLocation ( sink .getLocation ( ) )
885
+ )
886
+ }
887
+
888
+ predicate isBarrier = Config:: isBarrier / 1 ;
889
+
890
+ predicate isBarrierIn = Config:: isBarrierIn / 1 ;
891
+
892
+ predicate isBarrierOut = Config:: isBarrierOut / 1 ;
893
+
894
+ predicate isAdditionalFlowStep = Config:: isAdditionalFlowStep / 2 ;
895
+
896
+ predicate allowImplicitRead = Config:: allowImplicitRead / 2 ;
897
+
898
+ predicate neverSkip = Config:: neverSkip / 1 ;
899
+
900
+ predicate fieldFlowBranchLimit = Config:: fieldFlowBranchLimit / 0 ;
901
+
902
+ predicate accessPathLimit = Config:: accessPathLimit / 0 ;
903
+
904
+ predicate getAFeature = Config:: getAFeature / 0 ;
905
+
906
+ predicate sourceGrouping = Config:: sourceGrouping / 2 ;
907
+
908
+ predicate sinkGrouping = Config:: sinkGrouping / 2 ;
909
+
910
+ predicate includeHiddenNodes = Config:: includeHiddenNodes / 0 ;
911
+ }
912
+
913
+ /**
914
+ * This wrapper applies alert filters to an existing `StateConfigSig` module. It is intended to be
915
+ * used in the specific case where both the dataflow sources and the dataflow sinks are present in
916
+ * the query result, so we need to apply the alert filter on either the source or the sink (which
917
+ * is what this wrapper does).
918
+ */
919
+ module FilteredStateConfig< StateConfigSig Config> implements StateConfigSig {
920
+ private import codeql.util.AlertFiltering
921
+
922
+ private module AlertFiltering = AlertFilteringImpl< Location > ;
923
+
924
+ class FlowState = Config:: FlowState ;
925
+
926
+ pragma [ noinline]
927
+ private predicate hasFilteredSource ( ) {
928
+ exists ( Node n | Config:: isSource ( n , _) | AlertFiltering:: filterByLocation ( n .getLocation ( ) ) )
929
+ }
930
+
931
+ pragma [ noinline]
932
+ private predicate hasFilteredSink ( ) {
933
+ exists ( Node n |
934
+ Config:: isSink ( n , _) or
935
+ Config:: isSink ( n )
936
+ |
937
+ AlertFiltering:: filterByLocation ( n .getLocation ( ) )
938
+ )
939
+ }
940
+
941
+ predicate isSource ( Node source , FlowState state ) {
942
+ Config:: isSource ( source , state ) and
943
+ (
944
+ // If there are filtered sinks, we need to pass through all sources to preserve all alerts
945
+ // with filtered sinks. Otherwise the only alerts of interest are those with filtered
946
+ // sources, so we can perform the source filtering right here.
947
+ hasFilteredSink ( ) or
948
+ AlertFiltering:: filterByLocation ( source .getLocation ( ) )
949
+ )
950
+ }
951
+
952
+ predicate isSink ( Node sink , FlowState state ) {
953
+ Config:: isSink ( sink , state ) and
954
+ (
955
+ // If there are filtered sources, we need to pass through all sinks to preserve all alerts
956
+ // with filtered sources. Otherwise the only alerts of interest are those with filtered
957
+ // sinks, so we can perform the sink filtering right here.
958
+ hasFilteredSource ( ) or
959
+ AlertFiltering:: filterByLocation ( sink .getLocation ( ) )
960
+ )
961
+ }
962
+
963
+ predicate isSink ( Node sink ) {
964
+ Config:: isSink ( sink ) and
965
+ (
966
+ // If there are filtered sources, we need to pass through all sinks to preserve all alerts
967
+ // with filtered sources. Otherwise the only alerts of interest are those with filtered
968
+ // sinks, so we can perform the sink filtering right here.
969
+ hasFilteredSource ( ) or
970
+ AlertFiltering:: filterByLocation ( sink .getLocation ( ) )
971
+ )
972
+ }
973
+
974
+ predicate isBarrier = Config:: isBarrier / 1 ;
975
+
976
+ predicate isBarrier = Config:: isBarrier / 2 ;
977
+
978
+ predicate isBarrierIn = Config:: isBarrierIn / 1 ;
979
+
980
+ predicate isBarrierIn = Config:: isBarrierIn / 2 ;
981
+
982
+ predicate isBarrierOut = Config:: isBarrierOut / 1 ;
983
+
984
+ predicate isBarrierOut = Config:: isBarrierOut / 2 ;
985
+
986
+ predicate isAdditionalFlowStep = Config:: isAdditionalFlowStep / 2 ;
987
+
988
+ predicate isAdditionalFlowStep = Config:: isAdditionalFlowStep / 4 ;
989
+
990
+ predicate allowImplicitRead = Config:: allowImplicitRead / 2 ;
991
+
992
+ predicate neverSkip = Config:: neverSkip / 1 ;
993
+
994
+ predicate fieldFlowBranchLimit = Config:: fieldFlowBranchLimit / 0 ;
995
+
996
+ predicate accessPathLimit = Config:: accessPathLimit / 0 ;
997
+
998
+ predicate getAFeature = Config:: getAFeature / 0 ;
999
+
1000
+ predicate sourceGrouping = Config:: sourceGrouping / 2 ;
1001
+
1002
+ predicate sinkGrouping = Config:: sinkGrouping / 2 ;
1003
+
1004
+ predicate includeHiddenNodes = Config:: includeHiddenNodes / 0 ;
1005
+ }
838
1006
}
0 commit comments