@@ -24,38 +24,59 @@ class Unit = J::Unit;
24
24
25
25
class Callable = J:: Callable ;
26
26
27
- private J:: Method superImpl ( J:: Method m ) {
28
- result = m .getAnOverride ( ) and
29
- not exists ( result .getAnOverride ( ) ) and
30
- not m instanceof J:: ToStringMethod
31
- }
32
-
33
27
private predicate isInfrequentlyUsed ( J:: CompilationUnit cu ) {
34
28
cu .getPackage ( ) .getName ( ) .matches ( "javax.swing%" ) or
35
29
cu .getPackage ( ) .getName ( ) .matches ( "java.awt%" )
36
30
}
37
31
32
+ private predicate relevant ( Callable api ) {
33
+ api .isPublic ( ) and
34
+ api .getDeclaringType ( ) .isPublic ( ) and
35
+ api .fromSource ( ) and
36
+ not isUninterestingForModels ( api ) and
37
+ not isInfrequentlyUsed ( api .getCompilationUnit ( ) )
38
+ }
39
+
40
+ private J:: Method getARelevantOverride ( J:: Method m ) {
41
+ result = m .getAnOverride ( ) and
42
+ relevant ( result ) and
43
+ // Other exclusions for overrides.
44
+ not m instanceof J:: ToStringMethod
45
+ }
46
+
38
47
/**
39
- * Holds if it is relevant to generate models for `api`.
48
+ * Gets the super implementation of `m` if it is relevant.
49
+ * If such a super implementations does not exist, returns `m` if it is relevant.
40
50
*/
41
- private predicate isRelevantForModels ( Callable api ) {
42
- not isUninterestingForModels ( api ) and
43
- not isInfrequentlyUsed ( api .getCompilationUnit ( ) ) and
44
- // Disregard all APIs that have a manual model.
45
- not api = any ( FlowSummaryImpl:: Public:: SummarizedCallable sc | sc .applyManualModel ( ) ) .asCallable ( ) and
46
- not api =
47
- any ( FlowSummaryImpl:: Public:: NeutralSummaryCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
51
+ private J:: Callable liftedImpl ( J:: Callable m ) {
52
+ (
53
+ result = getARelevantOverride ( m )
54
+ or
55
+ result = m and relevant ( m )
56
+ ) and
57
+ not exists ( getARelevantOverride ( result ) )
58
+ }
59
+
60
+ private predicate hasManualModel ( Callable api ) {
61
+ api = any ( FlowSummaryImpl:: Public:: SummarizedCallable sc | sc .applyManualModel ( ) ) .asCallable ( ) or
62
+ api = any ( FlowSummaryImpl:: Public:: NeutralSummaryCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
48
63
}
49
64
50
65
/**
51
- * Holds if it is relevant to generate models for `api` based on data flow analysis.
66
+ * Holds if it is irrelevant to generate models for `api` based on data flow analysis.
67
+ *
68
+ * This serves as an extra filter for the `relevant` predicate.
52
69
*/
53
- predicate isRelevantForDataFlowModels ( Callable api ) {
54
- isRelevantForModels ( api ) and
55
- ( not api .getDeclaringType ( ) instanceof J:: Interface or exists ( api .getBody ( ) ) )
70
+ predicate isUninterestingForDataFlowModels ( Callable api ) {
71
+ api .getDeclaringType ( ) instanceof J:: Interface and not exists ( api .getBody ( ) )
56
72
}
57
73
58
- predicate isRelevantForTypeBasedFlowModels = isRelevantForModels / 1 ;
74
+ /**
75
+ * Holds if it is irrelevant to generate models for `api` based on type-based analysis.
76
+ *
77
+ * This serves as an extra filter for the `relevant` predicate.
78
+ */
79
+ predicate isUninterestingForTypeBasedFlowModels ( Callable api ) { none ( ) }
59
80
60
81
/**
61
82
* A class of Callables that are relevant for generating summary, source and sinks models for.
@@ -64,63 +85,54 @@ predicate isRelevantForTypeBasedFlowModels = isRelevantForModels/1;
64
85
* from outside the library itself.
65
86
*/
66
87
class TargetApiSpecific extends Callable {
88
+ private Callable lift ;
89
+
67
90
TargetApiSpecific ( ) {
68
- this .isPublic ( ) and
69
- this .fromSource ( ) and
70
- (
71
- this .getDeclaringType ( ) .isPublic ( ) or
72
- superImpl ( this ) .getDeclaringType ( ) .isPublic ( )
73
- ) and
74
- isRelevantForModels ( this )
91
+ lift = liftedImpl ( this ) and
92
+ not hasManualModel ( lift )
75
93
}
76
94
77
95
/**
78
- * Gets the callable that a model will be lifted to, if any .
96
+ * Gets the callable that a model will be lifted to.
79
97
*/
80
- Callable lift ( ) {
81
- exists ( Method m | m = superImpl ( this ) and m .fromSource ( ) | result = m )
82
- or
83
- not exists ( superImpl ( this ) ) and result = this
84
- }
98
+ Callable lift ( ) { result = lift }
85
99
}
86
100
87
- private string isExtensible ( J:: RefType ref ) {
88
- if ref .isFinal ( ) then result = "false" else result = "true"
89
- }
90
-
91
- private string typeAsModel ( J:: RefType type ) {
92
- result =
93
- type .getCompilationUnit ( ) .getPackage ( ) .getName ( ) + ";" +
94
- type .getErasure ( ) .( J:: RefType ) .nestedName ( )
95
- }
96
-
97
- private J:: RefType bestTypeForModel ( TargetApiSpecific api ) {
98
- result = api .lift ( ) .getDeclaringType ( )
101
+ private string isExtensible ( Callable c ) {
102
+ if c .getDeclaringType ( ) .isFinal ( ) then result = "false" else result = "true"
99
103
}
100
104
101
105
/**
102
- * Returns the appropriate type name for the model. Either the type
103
- * declaring the method or the supertype introducing the method.
106
+ * Returns the appropriate type name for the model.
104
107
*/
105
- private string typeAsSummaryModel ( TargetApiSpecific api ) {
106
- result = typeAsModel ( bestTypeForModel ( api ) )
108
+ private string typeAsModel ( Callable c ) {
109
+ exists ( RefType type | type = c .getDeclaringType ( ) |
110
+ result =
111
+ type .getCompilationUnit ( ) .getPackage ( ) .getName ( ) + ";" +
112
+ type .getErasure ( ) .( J:: RefType ) .nestedName ( )
113
+ )
107
114
}
108
115
109
- private predicate partialModel ( TargetApiSpecific api , string type , string name , string parameters ) {
110
- type = typeAsSummaryModel ( api ) and
111
- name = api .getName ( ) and
112
- parameters = ExternalFlow:: paramsString ( api )
116
+ private predicate partialLiftedModel (
117
+ TargetApiSpecific api , string type , string extensible , string name , string parameters
118
+ ) {
119
+ exists ( Callable c | c = api .lift ( ) |
120
+ type = typeAsModel ( c ) and
121
+ extensible = isExtensible ( c ) and
122
+ name = c .getName ( ) and
123
+ parameters = ExternalFlow:: paramsString ( c )
124
+ )
113
125
}
114
126
115
127
/**
116
128
* Computes the first 6 columns for MaD rows.
117
129
*/
118
130
string asPartialModel ( TargetApiSpecific api ) {
119
- exists ( string type , string name , string parameters |
120
- partialModel ( api , type , name , parameters ) and
131
+ exists ( string type , string extensible , string name , string parameters |
132
+ partialLiftedModel ( api , type , extensible , name , parameters ) and
121
133
result =
122
134
type + ";" //
123
- + isExtensible ( bestTypeForModel ( api ) ) + ";" //
135
+ + extensible + ";" //
124
136
+ name + ";" //
125
137
+ parameters + ";" //
126
138
+ /* ext + */ ";" //
@@ -132,7 +144,7 @@ string asPartialModel(TargetApiSpecific api) {
132
144
*/
133
145
string asPartialNeutralModel ( TargetApiSpecific api ) {
134
146
exists ( string type , string name , string parameters |
135
- partialModel ( api , type , name , parameters ) and
147
+ partialLiftedModel ( api , type , _ , name , parameters ) and
136
148
result =
137
149
type + ";" //
138
150
+ name + ";" //
@@ -228,6 +240,15 @@ predicate sinkModelSanitizer(DataFlow::Node node) {
228
240
)
229
241
}
230
242
243
+ private class ManualNeutralSinkCallable extends Callable {
244
+ ManualNeutralSinkCallable ( ) {
245
+ this =
246
+ any ( FlowSummaryImpl:: Public:: NeutralCallable nc |
247
+ nc .hasManualModel ( ) and nc .getKind ( ) = "sink"
248
+ ) .asCallable ( )
249
+ }
250
+ }
251
+
231
252
/**
232
253
* Holds if `source` is an api entrypoint relevant for creating sink models.
233
254
*/
@@ -236,14 +257,15 @@ predicate apiSource(DataFlow::Node source) {
236
257
source .asExpr ( ) .( J:: FieldAccess ) .isOwnFieldAccess ( ) or
237
258
source instanceof DataFlow:: ParameterNode
238
259
) and
239
- source .getEnclosingCallable ( ) .isPublic ( ) and
240
- exists ( J:: RefType t |
241
- t = source .getEnclosingCallable ( ) .getDeclaringType ( ) .getAnAncestor ( ) and
242
- not t instanceof J:: TypeObject and
243
- t .isPublic ( )
244
- ) and
245
- isRelevantForModels ( source .getEnclosingCallable ( ) ) and
246
- exists ( asPartialModel ( source .getEnclosingCallable ( ) ) )
260
+ exists ( Callable enclosing | enclosing = source .getEnclosingCallable ( ) |
261
+ exists ( liftedImpl ( enclosing ) ) and
262
+ not enclosing instanceof ManualNeutralSinkCallable and
263
+ exists ( J:: RefType t |
264
+ t = enclosing .getDeclaringType ( ) .getAnAncestor ( ) and
265
+ not t instanceof J:: TypeObject and
266
+ t .isPublic ( )
267
+ )
268
+ )
247
269
}
248
270
249
271
/**
0 commit comments