@@ -24,38 +24,52 @@ 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
66
* Holds if it is relevant to generate models for `api` based on data flow analysis.
52
67
*/
53
68
predicate isRelevantForDataFlowModels ( Callable api ) {
54
- isRelevantForModels ( api ) and
55
69
( not api .getDeclaringType ( ) instanceof J:: Interface or exists ( api .getBody ( ) ) )
56
70
}
57
71
58
- predicate isRelevantForTypeBasedFlowModels = isRelevantForModels / 1 ;
72
+ predicate isRelevantForTypeBasedFlowModels ( Callable api ) { any ( ) }
59
73
60
74
/**
61
75
* A class of Callables that are relevant for generating summary, source and sinks models for.
@@ -64,24 +78,17 @@ predicate isRelevantForTypeBasedFlowModels = isRelevantForModels/1;
64
78
* from outside the library itself.
65
79
*/
66
80
class TargetApiSpecific extends Callable {
81
+ private Callable lift ;
82
+
67
83
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 )
84
+ lift = liftedImpl ( this ) and
85
+ not hasManualModel ( lift )
75
86
}
76
87
77
88
/**
78
- * Gets the callable that a model will be lifted to, if any .
89
+ * Gets the callable that a model will be lifted to.
79
90
*/
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
- }
91
+ Callable lift ( ) { result = lift }
85
92
}
86
93
87
94
private string isExtensible ( J:: RefType ref ) {
@@ -228,6 +235,15 @@ predicate sinkModelSanitizer(DataFlow::Node node) {
228
235
)
229
236
}
230
237
238
+ private class ManualNeutralSinkCallable extends Callable {
239
+ ManualNeutralSinkCallable ( ) {
240
+ this =
241
+ any ( FlowSummaryImpl:: Public:: NeutralCallable nc |
242
+ nc .hasManualModel ( ) and nc .getKind ( ) = "sink"
243
+ ) .asCallable ( )
244
+ }
245
+ }
246
+
231
247
/**
232
248
* Holds if `source` is an api entrypoint relevant for creating sink models.
233
249
*/
@@ -236,14 +252,15 @@ predicate apiSource(DataFlow::Node source) {
236
252
source .asExpr ( ) .( J:: FieldAccess ) .isOwnFieldAccess ( ) or
237
253
source instanceof DataFlow:: ParameterNode
238
254
) 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 ( ) ) )
255
+ exists ( Callable enclosing | enclosing = source .getEnclosingCallable ( ) |
256
+ exists ( liftedImpl ( enclosing ) ) and
257
+ not enclosing instanceof ManualNeutralSinkCallable and
258
+ exists ( J:: RefType t |
259
+ t = enclosing .getDeclaringType ( ) .getAnAncestor ( ) and
260
+ not t instanceof J:: TypeObject and
261
+ t .isPublic ( )
262
+ )
263
+ )
247
264
}
248
265
249
266
/**
0 commit comments