Skip to content

Commit 7e11d8e

Browse files
Java: Add modelling for guava Sets
1 parent d1427fc commit 7e11d8e

File tree

1 file changed

+49
-2
lines changed

1 file changed

+49
-2
lines changed

java/ql/src/semmle/code/java/frameworks/guava/Collections.qll

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,9 @@ private class TableReadMethod extends TaintPreservingCallable {
187187
// Map<R,Map<C,V>> rowMap()
188188
// Map<C,Map<R,V>> columnMap()
189189
this
190-
.hasName(["put", "remove", "get", "row", "column", "cellSet", "values", "rowMap",
191-
"columnMap"])
190+
.hasName([
191+
"put", "remove", "get", "row", "column", "cellSet", "values", "rowMap", "columnMap"
192+
])
192193
}
193194

194195
override predicate returnsTaintFrom(int arg) { arg = -1 }
@@ -257,3 +258,49 @@ private class CopyOfMethod extends TaintPreservingCallable {
257258

258259
override predicate returnsTaintFrom(int arg) { arg = getNumberOfParameters() - 1 }
259260
}
261+
262+
/**
263+
* A taint-preserving static method of `com.google.common.collect.Sets`.
264+
*/
265+
private class SetsMethod extends TaintPreservingCallable {
266+
int arg;
267+
268+
SetsMethod() {
269+
this.getDeclaringType().hasQualifiedName(guavaCollectPackage(), "Sets") and
270+
this.isStatic() and
271+
(
272+
// static <E> HashSet<E> newHashSet(E... elements)
273+
// static <E> Set<E> newConcurrentHashSet(Iterable<? extends E> elements)
274+
// static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet(Iterable<? extends E> elements)
275+
// static <E extends Enum<E>>EnumSet<E> newEnumSet(Iterable<E> iterable, Class<E> elementType)
276+
// etc
277+
this.getName().matches("new%Set") and
278+
arg = 0
279+
or
280+
// static <B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets)
281+
// static <B> Set<List<B>> cartesianProduct(Set<? extends B>... sets)
282+
// static <E> Set<Set<E>> combinations(Set<E> set, int size)
283+
// static <E> Sets.SetView<E> difference(Set<E> set1, Set<?> set2)
284+
// static <E> NavigableSet<E> filter(NavigableSet<E> unfiltered, Predicate<? super E> predicate)
285+
// static <E> Set<E> filter(Set<E> unfiltered, Predicate<? super E> predicate)
286+
// static <E> SortedSet<E> filter(SortedSet<E> unfiltered, Predicate<? super E> predicate)
287+
// static <E> Set<Set<E>> powerSet(Set<E> set)
288+
// static <K extends Comparable<? super K>> NavigableSet<K>
289+
// static <E> NavigableSet<E> synchronizedNavigableSet(NavigableSet<E> navigableSet)
290+
// static <E> NavigableSet<E> unmodifiableNavigableSet(NavigableSet<E> set)
291+
this
292+
.hasName([
293+
"cartesianProduct", "combinations", "difference", "filter", "powerSet", "subSet",
294+
"synchronizedNavigableSet", "unmodifyableNavigableSet"
295+
]) and
296+
arg = 0
297+
or
298+
// static <E> Sets.SetView<E> symmetricDifference(Set<? extends E> set1, Set<? extends E> set2)
299+
// static <E> Sets.SetView<E> union(Set<? extends E> set1, Set<? extends E> set2)
300+
this.hasName(["symmetricDifference", "union"]) and
301+
arg = [0, 1]
302+
)
303+
}
304+
305+
override predicate returnsTaintFrom(int arg_) { arg_ = arg }
306+
}

0 commit comments

Comments
 (0)