@@ -89,81 +89,189 @@ class ContainerType extends RefType {
89
89
}
90
90
91
91
private predicate taintPreservingQualifierToMethod ( Method m ) {
92
+ // java.util.Map.Entry
92
93
m .getDeclaringType ( ) instanceof EntryType and
93
- m .hasName ( "getValue" )
94
+ m .hasName ( [ "getValue" , "setValue" ] )
94
95
or
96
+ // java.util.Iterable
95
97
m .getDeclaringType ( ) instanceof IterableType and
96
- m .hasName ( "iterator" )
98
+ m .hasName ( [ "iterator" , "spliterator" ] )
97
99
or
100
+ // java.util.Iterator
98
101
m .getDeclaringType ( ) instanceof IteratorType and
99
102
m .hasName ( "next" )
100
103
or
104
+ // java.util.ListIterator
105
+ m .getDeclaringType ( ) instanceof IteratorType and
106
+ m .hasName ( "previous" )
107
+ or
108
+ // java.util.Enumeration
101
109
m .getDeclaringType ( ) instanceof EnumerationType and
102
- m .hasName ( " nextElement")
110
+ m .hasName ( [ "asIterator" , " nextElement"] )
103
111
or
104
- m .( MapMethod ) .hasName ( "entrySet" )
112
+ // java.util.Map
113
+ m
114
+ .( MapMethod )
115
+ .hasName ( [ "computeIfAbsent" , "entrySet" , "get" , "getOrDefault" , "put" , "putIfAbsent" ,
116
+ "remove" , "replace" , "values" ] )
105
117
or
106
- m .( MapMethod ) .hasName ( "get" )
118
+ // java.util.Collection
119
+ m .( CollectionMethod ) .hasName ( [ "parallelStream" , "stream" , "toArray" ] )
107
120
or
108
- m .( MapMethod ) .hasName ( "remove" )
121
+ // java.util.List
122
+ m .( CollectionMethod ) .hasName ( [ "get" , "listIterator" , "set" , "subList" ] )
109
123
or
110
- m .( MapMethod ) .hasName ( "values " )
124
+ m .( CollectionMethod ) .hasName ( "remove" ) and m . getParameterType ( 0 ) . ( PrimitiveType ) . hasName ( "int ")
111
125
or
112
- m .( CollectionMethod ) .hasName ( "toArray" )
126
+ // java.util.Vector
127
+ m .( CollectionMethod ) .hasName ( [ "elementAt" , "elements" , "firstElement" , "lastElement" ] )
113
128
or
114
- m .( CollectionMethod ) .hasName ( "get" )
129
+ // java.util.Stack
130
+ m .( CollectionMethod ) .hasName ( [ "peek" , "pop" ] )
115
131
or
116
- m .( CollectionMethod ) .hasName ( "remove" ) and m .getParameterType ( 0 ) .( PrimitiveType ) .hasName ( "int" )
132
+ // java.util.Queue
133
+ m .( CollectionMethod ) .hasName ( [ "element" , "poll" ] )
117
134
or
118
135
m .( CollectionMethod ) .hasName ( "remove" ) and m .getNumberOfParameters ( ) = 0
119
136
or
120
- m .( CollectionMethod ) .hasName ( "subList" )
137
+ // java.util.Deque
138
+ m
139
+ .( CollectionMethod )
140
+ .hasName ( [ "getFirst" , "getLast" , "peekFirst" , "peekLast" , "pollFirst" , "pollLast" ,
141
+ "removeFirst" , "removeLast" ] )
142
+ or
143
+ // java.util.concurrent.BlockingQueue
144
+ // covered by Queue: poll(long, TimeUnit)
145
+ m .( CollectionMethod ) .hasName ( "take" )
146
+ or
147
+ // java.util.concurrent.BlockingDeque
148
+ // covered by Deque: pollFirst(long, TimeUnit), pollLast(long, TimeUnit)
149
+ m .( CollectionMethod ) .hasName ( [ "takeFirst" , "takeLast" ] )
150
+ or
151
+ // java.util.SortedSet
152
+ m .( CollectionMethod ) .hasName ( [ "first" , "headSet" , "last" , "subSet" , "tailSet" ] )
121
153
or
122
- m .( CollectionMethod ) .hasName ( "firstElement" )
154
+ // java.util.NavigableSet
155
+ // covered by Deque: pollFirst(), pollLast()
156
+ // covered by SortedSet: headSet(E, boolean), subSet(E, boolean, E, boolean) and tailSet(E, boolean)
157
+ m
158
+ .( CollectionMethod )
159
+ .hasName ( [ "ceiling" , "descendingIterator" , "descendingSet" , "floor" , "higher" , "lower" ] )
123
160
or
124
- m .( CollectionMethod ) .hasName ( "lastElement" )
161
+ // java.util.SortedMap
162
+ m .( MapMethod ) .hasName ( [ "headMap" , "subMap" , "tailMap" ] )
125
163
or
126
- m .( CollectionMethod ) .hasName ( "poll" )
164
+ // java.util.NavigableMap
165
+ // covered by SortedMap: headMap(K, boolean), subMap(K, boolean, K, boolean), tailMap(K, boolean)
166
+ m
167
+ .( MapMethod )
168
+ .hasName ( [ "ceilingEntry" , "descendingMap" , "firstEntry" , "floorEntry" , "higherEntry" ,
169
+ "lastEntry" , "lowerEntry" , "pollFirstEntry" , "pollLastEntry" ] )
127
170
or
128
- m .( CollectionMethod ) .hasName ( "peek" )
171
+ // java.util.Dictionary
172
+ m
173
+ .getDeclaringType ( )
174
+ .getSourceDeclaration ( )
175
+ .getASourceSupertype * ( )
176
+ .hasQualifiedName ( "java.util" , "Dictionary" ) and
177
+ m .hasName ( [ "elements" , "get" , "put" , "remove" ] )
129
178
or
130
- m .( CollectionMethod ) .hasName ( "element" )
179
+ // java.util.concurrent.ConcurrentHashMap
180
+ m .( MapMethod ) .hasName ( [ "elements" , "search" , "searchEntries" , "searchValues" ] )
131
181
}
132
182
133
183
private predicate qualifierToMethodStep ( Expr tracked , MethodAccess sink ) {
134
184
taintPreservingQualifierToMethod ( sink .getMethod ( ) ) and
135
185
tracked = sink .getQualifier ( )
136
186
}
137
187
138
- private predicate qualifierToArgumentStep ( Expr tracked , RValue sink ) {
139
- exists ( MethodAccess ma |
140
- ma .getMethod ( ) .( CollectionMethod ) .hasName ( "toArray" ) and
188
+ private predicate qualifierToArgumentStep ( Expr tracked , Expr sink ) {
189
+ exists ( MethodAccess ma , CollectionMethod method |
190
+ method = ma .getMethod ( ) and
191
+ (
192
+ // java.util.Vector
193
+ method .hasName ( "copyInto" )
194
+ or
195
+ // java.util.concurrent.BlockingQueue
196
+ method .hasName ( "drainTo" )
197
+ or
198
+ // java.util.Collection
199
+ method .hasName ( "toArray" ) and method .getParameter ( 0 ) .getType ( ) instanceof Array
200
+ ) and
141
201
tracked = ma .getQualifier ( ) and
142
- sink = ma .getArgument ( 1 )
202
+ sink = ma .getArgument ( 0 )
143
203
)
144
204
}
145
205
146
206
private predicate taintPreservingArgumentToQualifier ( Method method , int arg ) {
147
- method .( MapMethod ) .hasName ( "put" ) and arg = 1
207
+ // java.util.Map.Entry
208
+ method .getDeclaringType ( ) instanceof EntryType and
209
+ method .hasName ( "setValue" ) and
210
+ arg = 0
148
211
or
149
- method .( MapMethod ) .hasName ( "putAll" ) and arg = 0
212
+ // java.util.Map
213
+ method .( MapMethod ) .hasName ( [ "merge" , "put" , "putIfAbsent" ] ) and arg = 1
150
214
or
151
- method .( CollectionMethod ) .hasName ( "add " ) and arg = method .getNumberOfParameters ( ) - 1
215
+ method .( MapMethod ) .hasName ( "replace " ) and arg = method .getNumberOfParameters ( ) - 1
152
216
or
153
- method .( CollectionMethod ) .hasName ( "addAll" ) and arg = method .getNumberOfParameters ( ) - 1
217
+ method .( MapMethod ) .hasName ( "putAll" ) and arg = 0
218
+ or
219
+ // java.util.ListIterator
220
+ method .getDeclaringType ( ) instanceof IteratorType and
221
+ method .hasName ( [ "add" , "set" ] ) and
222
+ arg = 0
154
223
or
155
- method .( CollectionMethod ) .hasName ( "addElement" ) and arg = 0
224
+ // java.util.Collection
225
+ method .( CollectionMethod ) .hasName ( [ "add" , "addAll" ] ) and
226
+ // Refer to the last parameter to also cover List::add(int, E) and List::addAll(int, Collection)
227
+ arg = method .getNumberOfParameters ( ) - 1
156
228
or
229
+ // java.util.List
230
+ // covered by Collection: add(int, E), addAll(int, Collection<? extends E>)
157
231
method .( CollectionMethod ) .hasName ( "set" ) and arg = 1
158
232
or
233
+ // java.util.Vector
234
+ method .( CollectionMethod ) .hasName ( [ "addElement" , "insertElementAt" , "setElementAt" ] ) and arg = 0
235
+ or
236
+ // java.util.Stack
237
+ method .( CollectionMethod ) .hasName ( "push" ) and arg = 0
238
+ or
239
+ // java.util.Queue
159
240
method .( CollectionMethod ) .hasName ( "offer" ) and arg = 0
241
+ or
242
+ // java.util.Deque
243
+ // covered by Stack: push(E)
244
+ method .( CollectionMethod ) .hasName ( [ "addFirst" , "addLast" , "offerFirst" , "offerLast" ] ) and arg = 0
245
+ or
246
+ // java.util.concurrent.BlockingQueue
247
+ // covered by Queue: offer(E, long, TimeUnit)
248
+ method .( CollectionMethod ) .hasName ( "put" ) and arg = 0
249
+ or
250
+ // java.util.concurrent.TransferQueue
251
+ method .( CollectionMethod ) .hasName ( [ "transfer" , "tryTransfer" ] ) and arg = 0
252
+ or
253
+ // java.util.concurrent.BlockingDeque
254
+ // covered by Deque: offerFirst(E, long, TimeUnit), offerLast(E, long, TimeUnit)
255
+ method .( CollectionMethod ) .hasName ( [ "putFirst" , "putLast" ] ) and arg = 0
256
+ or
257
+ //java.util.Dictionary
258
+ method
259
+ .getDeclaringType ( )
260
+ .getSourceDeclaration ( )
261
+ .getASourceSupertype * ( )
262
+ .hasQualifiedName ( "java.util" , "Dictionary" ) and
263
+ method .hasName ( "put" ) and
264
+ arg = 1
160
265
}
161
266
162
267
/**
163
268
* Holds if `method` is a library method that returns tainted data if its
164
269
* `arg`th argument is tainted.
165
270
*/
166
271
private predicate taintPreservingArgumentToMethod ( Method method , int arg ) {
272
+ // java.util.Stack
273
+ method .( CollectionMethod ) .hasName ( "push" ) and arg = 0
274
+ or
167
275
method .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "Collections" ) and
168
276
(
169
277
method
0 commit comments