@@ -89,81 +89,189 @@ class ContainerType extends RefType {
8989}
9090
9191private predicate taintPreservingQualifierToMethod ( Method m ) {
92+ // java.util.Map.Entry
9293 m .getDeclaringType ( ) instanceof EntryType and
93- m .hasName ( "getValue" )
94+ m .hasName ( [ "getValue" , "setValue" ] )
9495 or
96+ // java.util.Iterable
9597 m .getDeclaringType ( ) instanceof IterableType and
96- m .hasName ( "iterator" )
98+ m .hasName ( [ "iterator" , "spliterator" ] )
9799 or
100+ // java.util.Iterator
98101 m .getDeclaringType ( ) instanceof IteratorType and
99102 m .hasName ( "next" )
100103 or
104+ // java.util.ListIterator
105+ m .getDeclaringType ( ) instanceof IteratorType and
106+ m .hasName ( "previous" )
107+ or
108+ // java.util.Enumeration
101109 m .getDeclaringType ( ) instanceof EnumerationType and
102- m .hasName ( " nextElement")
110+ m .hasName ( [ "asIterator" , " nextElement"] )
103111 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" ] )
105117 or
106- m .( MapMethod ) .hasName ( "get" )
118+ // java.util.Collection
119+ m .( CollectionMethod ) .hasName ( [ "parallelStream" , "stream" , "toArray" ] )
107120 or
108- m .( MapMethod ) .hasName ( "remove" )
121+ // java.util.List
122+ m .( CollectionMethod ) .hasName ( [ "get" , "listIterator" , "set" , "subList" ] )
109123 or
110- m .( MapMethod ) .hasName ( "values " )
124+ m .( CollectionMethod ) .hasName ( "remove" ) and m . getParameterType ( 0 ) . ( PrimitiveType ) . hasName ( "int ")
111125 or
112- m .( CollectionMethod ) .hasName ( "toArray" )
126+ // java.util.Vector
127+ m .( CollectionMethod ) .hasName ( [ "elementAt" , "elements" , "firstElement" , "lastElement" ] )
113128 or
114- m .( CollectionMethod ) .hasName ( "get" )
129+ // java.util.Stack
130+ m .( CollectionMethod ) .hasName ( [ "peek" , "pop" ] )
115131 or
116- m .( CollectionMethod ) .hasName ( "remove" ) and m .getParameterType ( 0 ) .( PrimitiveType ) .hasName ( "int" )
132+ // java.util.Queue
133+ m .( CollectionMethod ) .hasName ( [ "element" , "poll" ] )
117134 or
118135 m .( CollectionMethod ) .hasName ( "remove" ) and m .getNumberOfParameters ( ) = 0
119136 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" ] )
121153 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" ] )
123160 or
124- m .( CollectionMethod ) .hasName ( "lastElement" )
161+ // java.util.SortedMap
162+ m .( MapMethod ) .hasName ( [ "headMap" , "subMap" , "tailMap" ] )
125163 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" ] )
127170 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" ] )
129178 or
130- m .( CollectionMethod ) .hasName ( "element" )
179+ // java.util.concurrent.ConcurrentHashMap
180+ m .( MapMethod ) .hasName ( [ "elements" , "search" , "searchEntries" , "searchValues" ] )
131181}
132182
133183private predicate qualifierToMethodStep ( Expr tracked , MethodAccess sink ) {
134184 taintPreservingQualifierToMethod ( sink .getMethod ( ) ) and
135185 tracked = sink .getQualifier ( )
136186}
137187
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
141201 tracked = ma .getQualifier ( ) and
142- sink = ma .getArgument ( 1 )
202+ sink = ma .getArgument ( 0 )
143203 )
144204}
145205
146206private 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
148211 or
149- method .( MapMethod ) .hasName ( "putAll" ) and arg = 0
212+ // java.util.Map
213+ method .( MapMethod ) .hasName ( [ "merge" , "put" , "putIfAbsent" ] ) and arg = 1
150214 or
151- method .( CollectionMethod ) .hasName ( "add " ) and arg = method .getNumberOfParameters ( ) - 1
215+ method .( MapMethod ) .hasName ( "replace " ) and arg = method .getNumberOfParameters ( ) - 1
152216 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
154223 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
156228 or
229+ // java.util.List
230+ // covered by Collection: add(int, E), addAll(int, Collection<? extends E>)
157231 method .( CollectionMethod ) .hasName ( "set" ) and arg = 1
158232 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
159240 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
160265}
161266
162267/**
163268 * Holds if `method` is a library method that returns tainted data if its
164269 * `arg`th argument is tainted.
165270 */
166271private predicate taintPreservingArgumentToMethod ( Method method , int arg ) {
272+ // java.util.Stack
273+ method .( CollectionMethod ) .hasName ( "push" ) and arg = 0
274+ or
167275 method .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "Collections" ) and
168276 (
169277 method
0 commit comments