@@ -13,46 +13,55 @@ private import semmle.code.java.dispatch.VirtualDispatch
13
13
private import semmle.code.java.dataflow.internal.BaseSSA
14
14
private import semmle.code.java.controlflow.Guards
15
15
private import codeql.typeflow.TypeFlow
16
+ private import codeql.typeflow.UniversalFlow as UniversalFlow
16
17
17
- private module Input implements TypeFlowInput< Location > {
18
- private newtype TTypeFlowNode =
18
+ /** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
19
+ private RefType boxIfNeeded ( J:: Type t ) {
20
+ t .( PrimitiveType ) .getBoxedType ( ) = result or
21
+ result = t
22
+ }
23
+
24
+ /** Provides the input types and predicates for instantiation of `UniversalFlow`. */
25
+ module FlowStepsInput implements UniversalFlow:: UniversalFlowInput< Location > {
26
+ private newtype TFlowNode =
19
27
TField ( Field f ) { not f .getType ( ) instanceof PrimitiveType } or
20
28
TSsa ( BaseSsaVariable ssa ) { not ssa .getSourceVariable ( ) .getType ( ) instanceof PrimitiveType } or
21
29
TExpr ( Expr e ) or
22
30
TMethod ( Method m ) { not m .getReturnType ( ) instanceof PrimitiveType }
23
31
24
- /** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
25
- private RefType boxIfNeeded ( J:: Type t ) {
26
- t .( PrimitiveType ) .getBoxedType ( ) = result or
27
- result = t
28
- }
29
-
30
32
/**
31
33
* A `Field`, `BaseSsaVariable`, `Expr`, or `Method`.
32
34
*/
33
- class TypeFlowNode extends TTypeFlowNode {
35
+ class FlowNode extends TFlowNode {
36
+ /** Gets a textual representation of this element. */
34
37
string toString ( ) {
35
38
result = this .asField ( ) .toString ( ) or
36
39
result = this .asSsa ( ) .toString ( ) or
37
40
result = this .asExpr ( ) .toString ( ) or
38
41
result = this .asMethod ( ) .toString ( )
39
42
}
40
43
44
+ /** Gets the source location for this element. */
41
45
Location getLocation ( ) {
42
46
result = this .asField ( ) .getLocation ( ) or
43
47
result = this .asSsa ( ) .getLocation ( ) or
44
48
result = this .asExpr ( ) .getLocation ( ) or
45
49
result = this .asMethod ( ) .getLocation ( )
46
50
}
47
51
52
+ /** Gets the field corresponding to this node, if any. */
48
53
Field asField ( ) { this = TField ( result ) }
49
54
55
+ /** Gets the SSA variable corresponding to this node, if any. */
50
56
BaseSsaVariable asSsa ( ) { this = TSsa ( result ) }
51
57
58
+ /** Gets the expression corresponding to this node, if any. */
52
59
Expr asExpr ( ) { this = TExpr ( result ) }
53
60
61
+ /** Gets the method corresponding to this node, if any. */
54
62
Method asMethod ( ) { this = TMethod ( result ) }
55
63
64
+ /** Gets the type of this node. */
56
65
RefType getType ( ) {
57
66
result = this .asField ( ) .getType ( ) or
58
67
result = this .asSsa ( ) .getSourceVariable ( ) .getType ( ) or
@@ -61,8 +70,6 @@ private module Input implements TypeFlowInput<Location> {
61
70
}
62
71
}
63
72
64
- class Type = RefType ;
65
-
66
73
private SrcCallable viableCallable_v1 ( Call c ) {
67
74
result = viableImpl_v1 ( c )
68
75
or
@@ -88,7 +95,7 @@ private module Input implements TypeFlowInput<Location> {
88
95
*
89
96
* For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`.
90
97
*/
91
- predicate step ( TypeFlowNode n1 , TypeFlowNode n2 ) {
98
+ predicate step ( FlowNode n1 , FlowNode n2 ) {
92
99
n2 .asExpr ( ) .( ChooseExpr ) .getAResultExpr ( ) = n1 .asExpr ( )
93
100
or
94
101
exists ( Field f , Expr e |
@@ -134,7 +141,7 @@ private module Input implements TypeFlowInput<Location> {
134
141
/**
135
142
* Holds if `null` is the only value that flows to `n`.
136
143
*/
137
- predicate isNullValue ( TypeFlowNode n ) {
144
+ predicate isNullValue ( FlowNode n ) {
138
145
n .asExpr ( ) instanceof NullLiteral
139
146
or
140
147
exists ( LocalVariableDeclExpr decl |
@@ -144,11 +151,21 @@ private module Input implements TypeFlowInput<Location> {
144
151
)
145
152
}
146
153
147
- predicate isExcludedFromNullAnalysis ( TypeFlowNode n ) {
154
+ predicate isExcludedFromNullAnalysis ( FlowNode n ) {
148
155
// Fields that are never assigned a non-null value are probably set by
149
156
// reflection and are thus not always null.
150
157
exists ( n .asField ( ) )
151
158
}
159
+ }
160
+
161
+ private module Input implements TypeFlowInput< Location > {
162
+ import FlowStepsInput
163
+
164
+ class TypeFlowNode = FlowNode ;
165
+
166
+ predicate isExcludedFromNullAnalysis = FlowStepsInput:: isExcludedFromNullAnalysis / 1 ;
167
+
168
+ class Type = RefType ;
152
169
153
170
predicate exactTypeBase ( TypeFlowNode n , RefType t ) {
154
171
exists ( ClassInstanceExpr e |
0 commit comments