@@ -24,38 +24,59 @@ class Unit = J::Unit;
2424
2525class Callable = J:: Callable ;
2626
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-
3327private predicate isInfrequentlyUsed ( J:: CompilationUnit cu ) {
3428 cu .getPackage ( ) .getName ( ) .matches ( "javax.swing%" ) or
3529 cu .getPackage ( ) .getName ( ) .matches ( "java.awt%" )
3630}
3731
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+
3847/**
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.
4050 */
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 ( )
4863}
4964
5065/**
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.
5269 */
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 ( ) )
5672}
5773
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 ( ) }
5980
6081/**
6182 * A class of Callables that are relevant for generating summary, source and sinks models for.
@@ -64,63 +85,54 @@ predicate isRelevantForTypeBasedFlowModels = isRelevantForModels/1;
6485 * from outside the library itself.
6586 */
6687class TargetApiSpecific extends Callable {
88+ private Callable lift ;
89+
6790 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 )
7593 }
7694
7795 /**
78- * Gets the callable that a model will be lifted to, if any .
96+ * Gets the callable that a model will be lifted to.
7997 */
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 }
8599}
86100
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"
99103}
100104
101105/**
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.
104107 */
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+ )
107114}
108115
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+ )
113125}
114126
115127/**
116128 * Computes the first 6 columns for MaD rows.
117129 */
118130string 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
121133 result =
122134 type + ";" //
123- + isExtensible ( bestTypeForModel ( api ) ) + ";" //
135+ + extensible + ";" //
124136 + name + ";" //
125137 + parameters + ";" //
126138 + /* ext + */ ";" //
@@ -132,7 +144,7 @@ string asPartialModel(TargetApiSpecific api) {
132144 */
133145string asPartialNeutralModel ( TargetApiSpecific api ) {
134146 exists ( string type , string name , string parameters |
135- partialModel ( api , type , name , parameters ) and
147+ partialLiftedModel ( api , type , _ , name , parameters ) and
136148 result =
137149 type + ";" //
138150 + name + ";" //
@@ -228,6 +240,15 @@ predicate sinkModelSanitizer(DataFlow::Node node) {
228240 )
229241}
230242
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+
231252/**
232253 * Holds if `source` is an api entrypoint relevant for creating sink models.
233254 */
@@ -236,14 +257,15 @@ predicate apiSource(DataFlow::Node source) {
236257 source .asExpr ( ) .( J:: FieldAccess ) .isOwnFieldAccess ( ) or
237258 source instanceof DataFlow:: ParameterNode
238259 ) 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+ )
247269}
248270
249271/**
0 commit comments