@@ -9,44 +9,6 @@ class Uninitialized extends TaintKind {
99
1010}
1111
12- /** A source of an uninitialized variable.
13- * Either the start of the scope or a deletion.
14- */
15- class UninitializedSource extends TaintedDefinition {
16-
17- UninitializedSource ( ) {
18- exists ( FastLocalVariable var |
19- this .getSourceVariable ( ) = var and
20- not var .escapes ( ) |
21- this instanceof ScopeEntryDefinition
22- or
23- this instanceof DeletionDefinition
24- )
25- }
26-
27- override predicate isSourceOf ( TaintKind kind ) {
28- kind instanceof Uninitialized
29- }
30-
31- }
32-
33- /** A loop where we are guaranteed (or is at least likely) to execute the body at least once.
34- */
35- class AtLeastOnceLoop extends DataFlowExtension:: DataFlowVariable {
36-
37- AtLeastOnceLoop ( ) {
38- loop_entry_variables ( this , _)
39- }
40-
41- /* If we are guaranteed to iterate over a loop at least once, then we can prune any edges that
42- * don't pass through the body.
43- */
44- override predicate prunedSuccessor ( EssaVariable succ ) {
45- loop_entry_variables ( this , succ )
46- }
47-
48- }
49-
5012private predicate loop_entry_variables ( EssaVariable pred , EssaVariable succ ) {
5113 exists ( PhiFunction phi , BasicBlock pb |
5214 loop_entry_edge ( pb , phi .getBasicBlock ( ) ) and
@@ -64,43 +26,6 @@ private predicate loop_entry_edge(BasicBlock pred, BasicBlock loop) {
6426 )
6527}
6628
67- class UnitializedSanitizer extends Sanitizer {
68-
69- UnitializedSanitizer ( ) { this = "use of variable" }
70-
71- override
72- predicate sanitizingDefinition ( TaintKind taint , EssaDefinition def ) {
73- // An assignment cannot leave a variable uninitialized
74- taint instanceof Uninitialized and
75- (
76- def instanceof AssignmentDefinition
77- or
78- def instanceof ExceptionCapture
79- or
80- def instanceof ParameterDefinition
81- or
82- /* A use is a "sanitizer" of "uninitialized", as any use of an undefined
83- * variable will raise, making the subsequent code unreacahable.
84- */
85- exists ( def .( EssaNodeRefinement ) .getInput ( ) .getASourceUse ( ) )
86- or
87- exists ( def .( PhiFunction ) .getAnInput ( ) .getASourceUse ( ) )
88- or
89- exists ( def .( EssaEdgeRefinement ) .getInput ( ) .getASourceUse ( ) )
90- )
91- }
92-
93- override
94- predicate sanitizingNode ( TaintKind taint , ControlFlowNode node ) {
95- taint instanceof Uninitialized and
96- exists ( EssaVariable v |
97- v .getASourceUse ( ) = node and
98- not first_use ( node , v )
99- )
100- }
101-
102- }
103-
10429/** Since any use of a local will raise if it is uninitialized, then
10530 * any use dominated by another use of the same variable must be defined, or is unreachable.
10631 */
@@ -124,15 +49,75 @@ private predicate maybe_call_to_exiting_function(CallNode call) {
12449 )
12550}
12651
127- /** Prune edges where the predecessor block looks like it might contain a call to an exit function. */
128- class ExitFunctionGuardedEdge extends DataFlowExtension:: DataFlowVariable {
12952
130- override predicate prunedSuccessor ( EssaVariable succ ) {
131- exists ( CallNode exit_call |
132- succ .( PhiFunction ) .getInput ( exit_call .getBasicBlock ( ) ) = this and
133- maybe_call_to_exiting_function ( exit_call )
53+ predicate exitFunctionGuardedEdge ( EssaVariable pred , EssaVariable succ ) {
54+ exists ( CallNode exit_call |
55+ succ .( PhiFunction ) .getInput ( exit_call .getBasicBlock ( ) ) = pred and
56+ maybe_call_to_exiting_function ( exit_call )
57+ )
58+ }
59+
60+ class UninitializedConfig extends TaintTracking:: Configuration {
61+
62+ UninitializedConfig ( ) {
63+ this = "Unitialized local config"
64+ }
65+
66+ override predicate isSource ( DataFlow:: Node source , TaintKind kind ) {
67+ kind instanceof Uninitialized and
68+ exists ( EssaVariable var |
69+ source .asVariable ( ) = var and
70+ var .getSourceVariable ( ) instanceof FastLocalVariable and
71+ not var .getSourceVariable ( ) .( Variable ) .escapes ( ) |
72+ var instanceof ScopeEntryDefinition
73+ or
74+ var instanceof DeletionDefinition
13475 )
13576 }
13677
78+ override predicate isBarrier ( DataFlow:: Node node , TaintKind kind ) {
79+ kind instanceof Uninitialized and
80+ (
81+ definition ( node .asVariable ( ) )
82+ or
83+ use ( node .asVariable ( ) )
84+ or
85+ sanitizingNode ( node .asCfgNode ( ) )
86+ )
87+ }
88+
89+ private predicate definition ( EssaDefinition def ) {
90+ def instanceof AssignmentDefinition
91+ or
92+ def instanceof ExceptionCapture
93+ or
94+ def instanceof ParameterDefinition
95+ }
96+
97+ private predicate use ( EssaDefinition def ) {
98+ exists ( def .( EssaNodeRefinement ) .getInput ( ) .getASourceUse ( ) )
99+ or
100+ exists ( def .( PhiFunction ) .getAnInput ( ) .getASourceUse ( ) )
101+ or
102+ exists ( def .( EssaEdgeRefinement ) .getInput ( ) .getASourceUse ( ) )
103+ }
104+
105+ private predicate sanitizingNode ( ControlFlowNode node ) {
106+ exists ( EssaVariable v |
107+ v .getASourceUse ( ) = node and
108+ not first_use ( node , v )
109+ )
110+ }
111+
112+ override predicate isBarrierEdge ( DataFlow:: Node src , DataFlow:: Node dest ) {
113+ /* If we are guaranteed to iterate over a loop at least once, then we can prune any edges that
114+ * don't pass through the body.
115+ */
116+ loop_entry_variables ( src .asVariable ( ) , dest .asVariable ( ) )
117+ or
118+ exitFunctionGuardedEdge ( src .asVariable ( ) , dest .asVariable ( ) )
119+ }
120+
137121}
138122
123+
0 commit comments