-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathFlowSummary.qll
More file actions
141 lines (122 loc) · 4.26 KB
/
FlowSummary.qll
File metadata and controls
141 lines (122 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
* Provides classes and predicates for defining flow summaries.
*/
overlay[local?]
module;
import java
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowUtil
/** A synthetic callable with a set of concrete call sites and a flow summary. */
abstract class SyntheticCallable extends string {
bindingset[this]
SyntheticCallable() { any() }
/** Gets a call that targets this callable. */
abstract Call getACall();
/**
* Holds if data may flow from `input` to `output` through this callable.
*
* See `SummarizedCallable::propagatesFlow` for details.
*/
abstract predicate propagatesFlow(string input, string output, boolean preservesValue);
/**
* Gets the type of the parameter at the specified position with -1 indicating
* the instance parameter. If no types are provided then the types default to
* `Object`.
*/
Type getParameterType(int pos) { none() }
/**
* Gets the return type of this callable. If no type is provided then the type
* defaults to `Object`.
*/
Type getReturnType() { none() }
}
/**
* A module for importing frameworks that define synthetic callables.
*/
private module SyntheticCallables {
private import semmle.code.java.dispatch.WrappedInvocation
private import semmle.code.java.frameworks.android.Intent
private import semmle.code.java.frameworks.Stream
}
private newtype TSummarizedCallableBase =
TSimpleCallable(Callable c) { c.isSourceDeclaration() } or
TSyntheticCallable(SyntheticCallable c)
/**
* A callable that may have a flow summary. This is either a regular `Callable`
* or a `SyntheticCallable`.
*/
class SummarizedCallableBase extends TSummarizedCallableBase {
/** Gets a textual representation of this callable. */
string toString() { result = this.asCallable().toString() or result = this.asSyntheticCallable() }
/** Gets the source location for this callable. */
Location getLocation() {
result = this.asCallable().getLocation()
or
result.hasLocationInfo("", 0, 0, 0, 0) and
this instanceof TSyntheticCallable
}
/** Gets this callable cast as a `Callable`. */
Callable asCallable() { this = TSimpleCallable(result) }
/** Gets this callable cast as a `SyntheticCallable`. */
SyntheticCallable asSyntheticCallable() { this = TSyntheticCallable(result) }
/** Gets a call that targets this callable. */
Call getACall() {
result.getCallee().getSourceDeclaration() = this.asCallable()
or
result = this.asSyntheticCallable().getACall()
}
/**
* Gets the type of the parameter at the specified position with -1 indicating
* the instance parameter.
*/
Type getParameterType(int pos) {
result = this.asCallable().getParameterType(pos)
or
pos = -1 and result = this.asCallable().getDeclaringType()
or
result = this.asSyntheticCallable().getParameterType(pos)
or
exists(SyntheticCallable sc, Impl::Private::SummaryNode p | sc = this.asSyntheticCallable() |
Impl::Private::summaryParameterNode(p, pos) and
this = p.getSummarizedCallable() and
not exists(sc.getParameterType(pos)) and
result instanceof TypeObject
)
}
/** Gets the return type of this callable. */
Type getReturnType() {
result = this.asCallable().getReturnType()
or
exists(SyntheticCallable sc | sc = this.asSyntheticCallable() |
result = sc.getReturnType()
or
not exists(sc.getReturnType()) and
result instanceof TypeObject
)
}
}
class Provenance = Impl::Public::Provenance;
/** Provides the `Range` class used to define the extent of `SummarizedCallable`. */
module SummarizedCallable {
class Range = Impl::Public::SummarizedCallable;
}
class SummarizedCallable = Impl::Public::RelevantSummarizedCallable;
/**
* An adapter class to add the flow summaries specified on `SyntheticCallable`
* to `SummarizedCallable`.
*/
private class SummarizedSyntheticCallableAdapter extends SummarizedCallable::Range,
TSyntheticCallable
{
override predicate propagatesFlow(
string input, string output, boolean preservesValue, Provenance p, boolean isExact, string model
) {
exists(SyntheticCallable sc |
sc = this.asSyntheticCallable() and
sc.propagatesFlow(input, output, preservesValue) and
p = "manual" and
isExact = true and
model = sc
)
}
}