@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
2874
2874
}
2875
2875
}
2876
2876
2877
- /**
2878
- * A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
2879
- * Only those `PathNode`s that are reachable from a source are generated.
2880
- */
2881
- class PathNode extends TPathNode {
2882
- /** Gets a textual representation of this element. */
2883
- string toString ( ) { none ( ) }
2884
-
2885
- /**
2886
- * Gets a textual representation of this element, including a textual
2887
- * representation of the call context.
2888
- */
2889
- string toStringWithContext ( ) { none ( ) }
2890
-
2891
- /**
2892
- * Holds if this element is at the specified location.
2893
- * The location spans column `startcolumn` of line `startline` to
2894
- * column `endcolumn` of line `endline` in file `filepath`.
2895
- * For more information, see
2896
- * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
2897
- */
2898
- predicate hasLocationInfo (
2899
- string filepath , int startline , int startcolumn , int endline , int endcolumn
2900
- ) {
2901
- none ( )
2902
- }
2903
-
2904
- /** Gets the underlying `Node`. */
2905
- final Node getNode ( ) { this .( PathNodeImpl ) .getNodeEx ( ) .projectToNode ( ) = result }
2906
-
2877
+ abstract private class PathNodeImpl extends TPathNode {
2907
2878
/** Gets the `FlowState` of this node. */
2908
- FlowState getState ( ) { none ( ) }
2879
+ abstract FlowState getState ( ) ;
2909
2880
2910
2881
/** Gets the associated configuration. */
2911
- Configuration getConfiguration ( ) { none ( ) }
2912
-
2913
- /** Gets a successor of this node, if any. */
2914
- final PathNode getASuccessor ( ) {
2915
- result = this .( PathNodeImpl ) .getANonHiddenSuccessor ( ) and
2916
- reach ( this ) and
2917
- reach ( result )
2918
- }
2882
+ abstract Configuration getConfiguration ( ) ;
2919
2883
2920
2884
/** Holds if this node is a source. */
2921
- predicate isSource ( ) { none ( ) }
2922
- }
2885
+ abstract predicate isSource ( ) ;
2923
2886
2924
- abstract private class PathNodeImpl extends PathNode {
2925
2887
abstract PathNodeImpl getASuccessorImpl ( ) ;
2926
2888
2927
2889
private PathNodeImpl getASuccessorIfHidden ( ) {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
2967
2929
result = " <" + this .( PathNodeMid ) .getCallContext ( ) .toString ( ) + ">"
2968
2930
}
2969
2931
2970
- override string toString ( ) { result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) }
2932
+ /** Gets a textual representation of this element. */
2933
+ string toString ( ) { result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) }
2971
2934
2972
- override string toStringWithContext ( ) {
2973
- result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) + this .ppCtx ( )
2974
- }
2935
+ /**
2936
+ * Gets a textual representation of this element, including a textual
2937
+ * representation of the call context.
2938
+ */
2939
+ string toStringWithContext ( ) { result = this .getNodeEx ( ) .toString ( ) + this .ppAp ( ) + this .ppCtx ( ) }
2975
2940
2976
- override predicate hasLocationInfo (
2941
+ /**
2942
+ * Holds if this element is at the specified location.
2943
+ * The location spans column `startcolumn` of line `startline` to
2944
+ * column `endcolumn` of line `endline` in file `filepath`.
2945
+ * For more information, see
2946
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
2947
+ */
2948
+ predicate hasLocationInfo (
2977
2949
string filepath , int startline , int startcolumn , int endline , int endcolumn
2978
2950
) {
2979
2951
this .getNodeEx ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
2986
2958
}
2987
2959
2988
2960
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
2989
- private predicate reach ( PathNode n ) { directReach ( n ) or Subpaths:: retReach ( n ) }
2961
+ private predicate reach ( PathNodeImpl n ) { directReach ( n ) or Subpaths:: retReach ( n ) }
2990
2962
2991
2963
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
2992
- private predicate pathSucc ( PathNodeImpl n1 , PathNode n2 ) {
2964
+ private predicate pathSucc ( PathNodeImpl n1 , PathNodeImpl n2 ) {
2993
2965
n1 .getANonHiddenSuccessor ( ) = n2 and directReach ( n2 )
2994
2966
}
2995
2967
2996
- private predicate pathSuccPlus ( PathNode n1 , PathNode n2 ) = fastTC( pathSucc / 2 ) ( n1 , n2 )
2968
+ private predicate pathSuccPlus ( PathNodeImpl n1 , PathNodeImpl n2 ) = fastTC( pathSucc / 2 ) ( n1 , n2 )
2969
+
2970
+ /**
2971
+ * A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
2972
+ * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
2973
+ */
2974
+ class PathNode instanceof PathNodeImpl {
2975
+ PathNode ( ) { reach ( this ) }
2976
+
2977
+ /** Gets a textual representation of this element. */
2978
+ final string toString ( ) { result = super .toString ( ) }
2979
+
2980
+ /**
2981
+ * Gets a textual representation of this element, including a textual
2982
+ * representation of the call context.
2983
+ */
2984
+ final string toStringWithContext ( ) { result = super .toStringWithContext ( ) }
2985
+
2986
+ /**
2987
+ * Holds if this element is at the specified location.
2988
+ * The location spans column `startcolumn` of line `startline` to
2989
+ * column `endcolumn` of line `endline` in file `filepath`.
2990
+ * For more information, see
2991
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
2992
+ */
2993
+ final predicate hasLocationInfo (
2994
+ string filepath , int startline , int startcolumn , int endline , int endcolumn
2995
+ ) {
2996
+ super .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
2997
+ }
2998
+
2999
+ /** Gets the underlying `Node`. */
3000
+ final Node getNode ( ) { super .getNodeEx ( ) .projectToNode ( ) = result }
3001
+
3002
+ /** Gets the `FlowState` of this node. */
3003
+ final FlowState getState ( ) { result = super .getState ( ) }
3004
+
3005
+ /** Gets the associated configuration. */
3006
+ final Configuration getConfiguration ( ) { result = super .getConfiguration ( ) }
3007
+
3008
+ /** Gets a successor of this node, if any. */
3009
+ final PathNode getASuccessor ( ) { result = super .getANonHiddenSuccessor ( ) }
3010
+
3011
+ /** Holds if this node is a source. */
3012
+ final predicate isSource ( ) { super .isSource ( ) }
3013
+ }
2997
3014
2998
3015
/**
2999
3016
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
3004
3021
3005
3022
/** Holds if `n` is a node in the graph of data flow path explanations. */
3006
3023
query predicate nodes ( PathNode n , string key , string val ) {
3007
- reach ( n ) and key = "semmle.label" and val = n .toString ( )
3024
+ key = "semmle.label" and val = n .toString ( )
3008
3025
}
3009
3026
3010
3027
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
3013
3030
* `ret -> out` is summarized as the edge `arg -> out`.
3014
3031
*/
3015
3032
query predicate subpaths ( PathNode arg , PathNode par , PathNode ret , PathNode out ) {
3016
- Subpaths:: subpaths ( arg , par , ret , out ) and
3017
- reach ( arg ) and
3018
- reach ( par ) and
3019
- reach ( ret ) and
3020
- reach ( out )
3033
+ Subpaths:: subpaths ( arg , par , ret , out )
3021
3034
}
3022
3035
}
3023
3036
@@ -3399,22 +3412,22 @@ private module Subpaths {
3399
3412
*/
3400
3413
pragma [ nomagic]
3401
3414
private predicate subpaths02 (
3402
- PathNode arg , ParamNodeEx par , SummaryCtxSome sc , CallContext innercc , ReturnKindExt kind ,
3415
+ PathNodeImpl arg , ParamNodeEx par , SummaryCtxSome sc , CallContext innercc , ReturnKindExt kind ,
3403
3416
NodeEx out , FlowState sout , AccessPath apout
3404
3417
) {
3405
3418
subpaths01 ( arg , par , sc , innercc , kind , out , sout , apout ) and
3406
3419
out .asNode ( ) = kind .getAnOutNode ( _)
3407
3420
}
3408
3421
3409
3422
pragma [ nomagic]
3410
- private Configuration getPathNodeConf ( PathNode n ) { result = n .getConfiguration ( ) }
3423
+ private Configuration getPathNodeConf ( PathNodeImpl n ) { result = n .getConfiguration ( ) }
3411
3424
3412
3425
/**
3413
3426
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
3414
3427
*/
3415
3428
pragma [ nomagic]
3416
3429
private predicate subpaths03 (
3417
- PathNode arg , ParamNodeEx par , PathNodeMid ret , NodeEx out , FlowState sout , AccessPath apout
3430
+ PathNodeImpl arg , ParamNodeEx par , PathNodeMid ret , NodeEx out , FlowState sout , AccessPath apout
3418
3431
) {
3419
3432
exists ( SummaryCtxSome sc , CallContext innercc , ReturnKindExt kind , RetNodeEx retnode |
3420
3433
subpaths02 ( arg , par , sc , innercc , kind , out , sout , apout ) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
3444
3457
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
3445
3458
* `ret -> out` is summarized as the edge `arg -> out`.
3446
3459
*/
3447
- predicate subpaths ( PathNodeImpl arg , PathNodeImpl par , PathNodeImpl ret , PathNode out ) {
3460
+ predicate subpaths ( PathNodeImpl arg , PathNodeImpl par , PathNodeImpl ret , PathNodeImpl out ) {
3448
3461
exists ( ParamNodeEx p , NodeEx o , FlowState sout , AccessPath apout , PathNodeMid out0 |
3449
3462
pragma [ only_bind_into ] ( arg ) .getANonHiddenSuccessor ( ) = pragma [ only_bind_into ] ( out0 ) and
3450
3463
subpaths03 ( pragma [ only_bind_into ] ( arg ) , p , localStepToHidden * ( ret ) , o , sout , apout ) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
3460
3473
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
3461
3474
*/
3462
3475
predicate retReach ( PathNodeImpl n ) {
3463
- exists ( PathNode out | subpaths ( _, _, n , out ) | directReach ( out ) or retReach ( out ) )
3476
+ exists ( PathNodeImpl out | subpaths ( _, _, n , out ) | directReach ( out ) or retReach ( out ) )
3464
3477
or
3465
3478
exists ( PathNodeImpl mid |
3466
3479
retReach ( mid ) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
3477
3490
* sinks.
3478
3491
*/
3479
3492
private predicate flowsTo (
3480
- PathNode flowsource , PathNodeSink flowsink , Node source , Node sink , Configuration configuration
3493
+ PathNodeImpl flowsource , PathNodeSink flowsink , Node source , Node sink ,
3494
+ Configuration configuration
3481
3495
) {
3482
3496
flowsource .isSource ( ) and
3483
3497
flowsource .getConfiguration ( ) = configuration and
3484
- flowsource .( PathNodeImpl ) . getNodeEx ( ) .asNode ( ) = source and
3498
+ flowsource .getNodeEx ( ) .asNode ( ) = source and
3485
3499
( flowsource = flowsink or pathSuccPlus ( flowsource , flowsink ) ) and
3486
3500
flowsink .getNodeEx ( ) .asNode ( ) = sink
3487
3501
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
3504
3518
fields = count ( TypedContent f0 | exists ( PathNodeMid pn | pn .getAp ( ) .getHead ( ) = f0 ) ) and
3505
3519
conscand = count ( AccessPath ap | exists ( PathNodeMid pn | pn .getAp ( ) = ap ) ) and
3506
3520
states = count ( FlowState state | exists ( PathNodeMid pn | pn .getState ( ) = state ) ) and
3507
- tuples = count ( PathNode pn )
3521
+ tuples = count ( PathNodeImpl pn )
3508
3522
or
3509
3523
fwd = false and
3510
3524
nodes = count ( NodeEx n0 | exists ( PathNodeImpl pn | pn .getNodeEx ( ) = n0 and reach ( pn ) ) ) and
3511
3525
fields = count ( TypedContent f0 | exists ( PathNodeMid pn | pn .getAp ( ) .getHead ( ) = f0 and reach ( pn ) ) ) and
3512
3526
conscand = count ( AccessPath ap | exists ( PathNodeMid pn | pn .getAp ( ) = ap and reach ( pn ) ) ) and
3513
3527
states = count ( FlowState state | exists ( PathNodeMid pn | pn .getState ( ) = state and reach ( pn ) ) ) and
3514
- tuples = count ( PathNode pn | reach ( pn ) )
3528
+ tuples = count ( PathNode pn )
3515
3529
}
3516
3530
3517
3531
/**
0 commit comments