Packaging: Java refactoring

Split java pack into `codeql/java-all` and `codeql/java-queries`.
This commit is contained in:
Andrew Eisenberg
2021-08-18 13:43:21 -07:00
parent 39533317ff
commit 8e750f18ad
326 changed files with 41 additions and 12 deletions

View File

@@ -0,0 +1,98 @@
/** Definitions of flow steps through utility methods of `com.google.common.base`. */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class GuavaBaseCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
"com.google.common.base;Strings;false;emptyToNull;(String);;Argument[0];ReturnValue;value",
"com.google.common.base;Strings;false;nullToEmpty;(String);;Argument[0];ReturnValue;value",
"com.google.common.base;Strings;false;padStart;(String,int,char);;Argument[0];ReturnValue;taint",
"com.google.common.base;Strings;false;padEnd;(String,int,char);;Argument[0];ReturnValue;taint",
"com.google.common.base;Strings;false;repeat;(String,int);;Argument[0];ReturnValue;taint",
"com.google.common.base;Strings;false;lenientFormat;(String,Object[]);;Argument[0];ReturnValue;taint",
"com.google.common.base;Strings;false;lenientFormat;(String,Object[]);;ArrayElement of Argument[1];ReturnValue;taint",
"com.google.common.base;Joiner;false;on;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner;false;skipNulls;();;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner;false;useForNull;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner;false;withKeyValueSeparator;(char);;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;Argument[1..2];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;ArrayElement of Argument[3];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Iterable);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Iterator);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;Argument[1..2];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;ArrayElement of Argument[3];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterable);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterator);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;;;Argument[-1];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;;;Argument[0];ReturnValue;value",
"com.google.common.base;Joiner;false;join;;;Argument[-1..2];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[1];Argument[0];taint",
"com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[0];ReturnValue;value",
"com.google.common.base;Joiner$MapJoiner;false;join;;;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;MapKey of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;MapValue of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;MapKey of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;MapValue of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Map);;MapKey of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Map);;MapValue of Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter;false;splitToStream;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Preconditions;false;checkNotNull;;;Argument[0];ReturnValue;value",
"com.google.common.base;Verify;false;verifyNotNull;;;Argument[0];ReturnValue;value",
"com.google.common.base;Ascii;false;toLowerCase;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;toLowerCase;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;toUpperCase;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;toUpperCase;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[2];ReturnValue;taint",
"com.google.common.base;CaseFormat;true;to;(CaseFormat,String);;Argument[1];ReturnValue;taint",
"com.google.common.base;Converter;true;apply;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;Converter;true;convert;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;Converter;true;convertAll;(Iterable);;Element of Argument[0];Element of ReturnValue;taint",
"com.google.common.base;Supplier;true;get;();;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;ofInstance;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;memoize;(Supplier);;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;memoizeWithExpiration;(Supplier,long,TimeUnit);;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;synchronizedSupplier;(Supplier);;Argument[0];ReturnValue;taint",
"com.google.common.base;Optional;true;fromJavaUtil;(Optional);;Element of Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;fromNullable;(Object);;Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;get;();;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;asSet;();;Element of Argument[-1];Element of ReturnValue;value",
"com.google.common.base;Optional;true;of;(Object);;Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;or;(Optional);;Element of Argument[-1..0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;or;(Supplier);;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;or;(Supplier);;Argument[0];ReturnValue;taint",
"com.google.common.base;Optional;true;or;(Object);;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;or;(Object);;Argument[0];ReturnValue;value",
"com.google.common.base;Optional;true;orNull;();;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;presentInstances;(Iterable);;Element of Element of Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;toJavaUtil;();;Element of Argument[-1];Element of ReturnValue;value",
"com.google.common.base;Optional;true;toJavaUtil;(Optional);;Element of Argument[0];Element of ReturnValue;value",
"com.google.common.base;MoreObjects;false;firstNonNull;(Object,Object);;Argument[0..1];ReturnValue;value",
"com.google.common.base;MoreObjects;false;toStringHelper;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];Argument[-1];taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[-1];ReturnValue;value",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];Argument[-1];taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;addValue;;;Argument[-1];ReturnValue;value",
"com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];Argument[-1];taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;omitNullValues;();;Argument[-1];ReturnValue;value",
"com.google.common.base;MoreObjects$ToStringHelper;false;toString;();;Argument[-1];ReturnValue;taint"
]
}
}

View File

@@ -0,0 +1,32 @@
/** Flow steps through methods of `com.google.common.cache` */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class GuavaBaseCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
"com.google.common.cache;Cache;true;asMap;();;MapKey of Argument[-1];MapKey of ReturnValue;value",
"com.google.common.cache;Cache;true;asMap;();;MapValue of Argument[-1];MapValue of ReturnValue;value",
// lambda flow from Argument[1] not implemented
"com.google.common.cache;Cache;true;get;(Object,Callable);;MapValue of Argument[-1];ReturnValue;value",
"com.google.common.cache;Cache;true;getIfPresent;(Object);;MapValue of Argument[-1];ReturnValue;value",
// the true flow to MapKey of ReturnValue for getAllPresent is the intersection of the these inputs, but intersections cannot be modelled fully accurately.
"com.google.common.cache;Cache;true;getAllPresent;(Iterable);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"com.google.common.cache;Cache;true;getAllPresent;(Iterable);;Element of Argument[0];MapKey of ReturnValue;value",
"com.google.common.cache;Cache;true;getAllPresent;(Iterable);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"com.google.common.cache;Cache;true;put;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"com.google.common.cache;Cache;true;put;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"com.google.common.cache;Cache;true;putAll;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"com.google.common.cache;Cache;true;putAll;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
"com.google.common.cache;LoadingCache;true;get;(Object);;MapValue of Argument[-1];ReturnValue;value",
"com.google.common.cache;LoadingCache;true;getUnchecked;(Object);;MapValue of Argument[-1];ReturnValue;value",
"com.google.common.cache;LoadingCache;true;apply;(Object);;MapValue of Argument[-1];ReturnValue;value",
"com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Element of Argument[0];MapKey of ReturnValue;value",
"com.google.common.cache;LoadingCache;true;getAll;(Iterable);;Element of Argument[0];MapKey of Argument[-1];value",
"com.google.common.cache;LoadingCache;true;getAll;(Iterable);;MapValue of Argument[-1];MapValue of ReturnValue;value"
]
}
}

View File

@@ -0,0 +1,360 @@
/** Definitions of flow steps through the collection types in the Guava framework */
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSteps
private import semmle.code.java.Collections
private string guavaCollectPackage() { result = "com.google.common.collect" }
/** A reference type that extends a parameterization of one of the various immutable container types. */
private class ImmutableContainerType extends RefType {
string kind;
ImmutableContainerType() {
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName(guavaCollectPackage(), kind) and
kind = ["ImmutableCollection", "ImmutableMap", "ImmutableMultimap", "ImmutableTable"]
}
/**
* Gets the name of the most general superclass of this type
* from among `ImmutableCollection`, `ImmutableMap`, `ImmutableMultimap`, and `ImmutableTable`.
*/
string getKind() { result = kind }
}
/** A nested `Builder` class of one of the various immutable container classes */
private class ContainerBuilder extends NestedType {
ContainerBuilder() {
this.hasName("Builder") and
this.getEnclosingType() instanceof ImmutableContainerType
}
}
private class BuilderBuildMethod extends TaintPreservingCallable {
BuilderBuildMethod() {
this.getDeclaringType().getASourceSupertype*() instanceof ContainerBuilder and
// abstract ImmutableCollection<E> build()
// similar for other builder types
this.hasName("build")
}
override predicate returnsTaintFrom(int arg) { arg = -1 }
}
/** A method on a `Builder` class that adds elements to the container being built */
private class BuilderAddMethod extends TaintPreservingCallable {
int argument;
BuilderAddMethod() {
this.getDeclaringType().getASourceSupertype*() instanceof ContainerBuilder and
(
// abstract ImmutableCollection.Builder<E> add(E element)
// ImmutableCollection.Builder<E> add(E... elements)
// ImmutableCollection.Builder<E> addAll(Iterable<? extends E> elements)
// ImmutableCollection.Builder<E> addAll(Iterator<? extends E> elements)
// ImmutableMultiset.Builder<E> addCopies(E element, int occurrences)
// ImmutableMultiset.Builder<E> setCount(E element, int count)
this.hasName(["add", "addAll", "addCopies", "setCount"]) and
argument = 0
or
// ImmutableMap.Builder<K,V> put(K key, V value)
// ImmutableMap.Builder<K,V> put(Map.Entry<? extends K,? extends V> entry)
// ImmutableMap.Builder<K,V> putAll(Map<? extends K,? extends V> map)
// ImmutableMap.Builder<K,V> putAll(Iterable<? extends Map.Entry<? extends K,? extends V>> entries)
// ImmutableMultimap.Builder<K,V> put(K key, V value)
// ImmutableMultimap.Builder<K,V> put(Map.Entry<? extends K,? extends V> entry)
// ImmutableMultimap.Builder<K,V> putAll(Iterable<? extends Map.Entry<? extends K,? extends V>> entries)
// ImmutableMultimap.Builder<K,V> putAll(K key, Iterable<? extends V> values)
// ImmutableMultimap.Builder<K,V> putAll(K key, V... values)
// ImmutableMultimap.Builder<K,V> putAll(Multimap<? extends K,? extends V> multimap)
// ImmutableTable.Builder<R,C,V> put(R rowKey, C columnKey, V value)
// ImmutableTable.Builder<R,C,V> put(Table.Cell<? extends R,? extends C,? extends V> cell)
// ImmutableTable.Builder<R,C,V> putAll(Table<? extends R,? extends C,? extends V> table)
this.hasName(["put", "putAll"]) and
argument = getNumberOfParameters() - 1
)
}
override predicate returnsTaintFrom(int arg) { arg = [-1, argument] }
override predicate transfersTaint(int src, int sink) { src = argument and sink = -1 }
}
/**
* In a chained call `b.add(x).add(y).add(z)`, represents a flow step from the return value of
* this expression to the post update node of `b` (valid because the builder add methods return their qualifier).
* This is sufficient to express flow from `y` and `z` to `b`.
*/
private class ChainedBuilderAddStep extends AdditionalTaintStep {
override predicate step(DataFlow::Node src, DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof BuilderAddMethod and
src.asExpr() = ma and
chainedBuilderMethod+(sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) = ma
)
}
}
private MethodAccess chainedBuilderMethod(Expr e) {
result.getQualifier() = e and
result.getMethod() instanceof BuilderAddMethod
}
/**
* A reference type that extends a parameterization of `com.google.common.collect.Multimap`.
*/
class MultimapType extends RefType {
MultimapType() {
this.getSourceDeclaration()
.getASourceSupertype*()
.hasQualifiedName(guavaCollectPackage(), "Multimap")
}
/** Gets the type of keys stored in this map. */
RefType getKeyType() {
exists(GenericInterface map | map.hasQualifiedName(guavaCollectPackage(), "Multimap") |
indirectlyInstantiates(this, map, 0, result)
)
}
/** Gets the type of values stored in this map. */
RefType getValueType() {
exists(GenericInterface map | map.hasQualifiedName(guavaCollectPackage(), "Multimap") |
indirectlyInstantiates(this, map, 1, result)
)
}
}
private class MultimapWriteMethod extends TaintPreservingCallable {
MultimapWriteMethod() {
this.getDeclaringType() instanceof MultimapType and
// boolean put(K key, V value)
// boolean putAll(K key, Iterable<? extends V> values)
// boolean putAll(Multimap<? extends K,? extends V> multimap)
// Collection<V> replaceValues(K key, Iterable<? extends V> values)
this.hasName(["put", "putAll", "replaceValues"])
}
override predicate transfersTaint(int src, int sink) {
src = getNumberOfParameters() - 1 and
sink = -1
}
}
private class MultimapReadMethod extends TaintPreservingCallable {
MultimapReadMethod() {
this.getDeclaringType() instanceof MultimapType and
// Collection<V> replaceValues(K key, Iterable<? extends V> values)
// Collection<V> removeAll(@CompatibleWith("K") Object key)
// Collection<V> get(K key)
// Collection<V> values()
// Collection<Map.Entry<K,V>> entries()
// Map<K,Collection<V>> asMap()
this.hasName(["replaceValues", "removeAll", "get", "values", "entries", "asMap"])
}
override predicate returnsTaintFrom(int arg) { arg = -1 }
// Not implemented: Some of these methods return "views", which when modified will modify the map itself.
// However, taint flow from these views to the map is not implemented.
}
/**
* A reference type that extends a parameterization of `com.google.common.collect.Table`.
*/
class TableType extends RefType {
TableType() {
this.getSourceDeclaration()
.getASourceSupertype*()
.hasQualifiedName(guavaCollectPackage(), "Table")
}
/** Gets the type of row keys stored in this table. */
RefType getRowType() {
exists(GenericInterface table | table.hasQualifiedName(guavaCollectPackage(), "Table") |
indirectlyInstantiates(this, table, 0, result)
)
}
/** Gets the type of column keys stored in this table. */
RefType getColumnType() {
exists(GenericInterface table | table.hasQualifiedName(guavaCollectPackage(), "Table") |
indirectlyInstantiates(this, table, 1, result)
)
}
/** Gets the type of values stored in this table. */
RefType getValueType() {
exists(GenericInterface table | table.hasQualifiedName(guavaCollectPackage(), "Table") |
indirectlyInstantiates(this, table, 2, result)
)
}
}
private class TableWriteMethod extends TaintPreservingCallable {
TableWriteMethod() {
this.getDeclaringType() instanceof TableType and
// V put(R rowKey, C columnKey, V value)
// void putAll(Table<? extends R,? extends C,? extends V> table)
this.hasName(["put", "putAll"])
}
override predicate transfersTaint(int src, int sink) {
src = getNumberOfParameters() - 1 and
sink = -1
}
}
private class TableReadMethod extends TaintPreservingCallable {
TableReadMethod() {
this.getDeclaringType() instanceof TableType and
// V put(R rowKey, C columnKey, V value)
// V remove(@CompatibleWith("R") Object rowKey, @CompatibleWith("C") Object columnKey)
// V get(@CompatibleWith("R") Object rowKey, @CompatibleWith("C") Object columnKey)
// Map<C,V> row(R rowKey)
// Map<R,V> column(C columnKey)
// Set<Table.Cell<R,C,V>> cellSet()
// Collection<V> values()
// Map<R,Map<C,V>> rowMap()
// Map<C,Map<R,V>> columnMap()
this.hasName([
"put", "remove", "get", "row", "column", "cellSet", "values", "rowMap", "columnMap"
])
}
override predicate returnsTaintFrom(int arg) { arg = -1 }
// Not implemented: Some of these methods return "views", which when modified will modify the table itself.
// However, taint flow from these views to the table is not implemented.
}
private class TableCellReadMethod extends TaintPreservingCallable {
TableCellReadMethod() {
exists(NestedType cell |
cell.getEnclosingType() instanceof TableType and
cell.hasName("Cell") and
this.getDeclaringType().getSourceDeclaration().getASourceSupertype*() = cell and
// V getValue()
this.hasName("getValue")
)
}
override predicate returnsTaintFrom(int arg) { arg = -1 }
}
/**
* An `of` static method on the various immutable container types.
*/
private class OfMethod extends TaintPreservingCallable {
string kind;
OfMethod() {
this.getDeclaringType().(ImmutableContainerType).getKind() = kind and
// static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
// static <K,V> ImmutableMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4)
// static <K,V> ImmutableMultimap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4)
// static <R,C,V> ImmutableTable<R,C,V> of(R rowKey, C columnKey, V value)
// etc for other types and numbers of parameters
this.hasName("of") and
this.isStatic()
}
override predicate returnsTaintFrom(int arg) {
arg = [0 .. getNumberOfParameters()] and
(kind.regexpMatch(".*[Mm]ap") implies arg % 2 = 1) and
(kind = "ImmutableTable" implies arg % 3 = 2)
}
}
private class ComparatorType extends RefType {
ComparatorType() { this.getASourceSupertype*().hasQualifiedName("java.util", "Comparator") }
}
/**
* A `copyOf`, `sortedCopyOf`, or `copyOfSorted` static method on the various immutable container types.
*/
private class CopyOfMethod extends TaintPreservingCallable {
CopyOfMethod() {
this.getDeclaringType() instanceof ImmutableContainerType and
// static <E> ImmutableList<E> copyOf(E[] elements)
// static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements)
// static <E> ImmutableList<E> copyOf(Collection<? extends E> elements)
// static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements)
// static <E extends Comparable<? super E>> ImmutableList<E> sortedCopyOf(Iterable<? extends E> elements)
// static <E> ImmutableList<E> sortedCopyOf(Comparator<? super E> comparator, Iterable<? extends E> elements)
// static <K,V> ImmutableMap<K,V> copyOf(Map<? extends K,? extends V> map)
// static <K,V> ImmutableMap<K,V> copyOf(Iterable<? extends Map.Entry<? extends K,? extends V>> entries)
// static <K,V> ImmutableMultimap<K,V> copyOf(Multimap<? extends K,? extends V> multimap)
// static <K,V> ImmutableMultimap<K,V> copyOf(Iterable<? extends Map.Entry<? extends K,? extends V>> entries)
// static <R,C,V> ImmutableTable<R,C,V> copyOf(Table<? extends R,? extends C,? extends V> table)
// static <K, V> ImmutableSortedMap<K, V> copyOf(Map<? extends K, ? extends V> map)
// static <K, V> ImmutableSortedMap<K, V> copyOf(Map<? extends K, ? extends V> map, Comparator<? super K> comparator)
// static <K, V> ImmutableSortedMap<K, V> copyOfSorted(SortedMap<K, ? extends V> map)
// static <E> ImmutableSortedSet<E> copyOf(Iterator<? extends E> elements)
// static <E> ImmutableSortedSet<E> copyOf(Comparator<? super E> comparator, Iterator<? extends E> elements)
// static <E> ImmutableSortedSet<E> copyOfSorted(SortedSet<E> sortedSet)
// etc
this.hasName(["copyOf", "sortedCopyOf", "copyOfSorted"]) and
this.isStatic()
}
override predicate returnsTaintFrom(int arg) {
arg = [0 .. getNumberOfParameters()] and
not getParameterType(arg) instanceof ComparatorType
}
}
private class CollectionAsListMethod extends TaintPreservingCallable {
CollectionAsListMethod() {
this.getDeclaringType()
.getASourceSupertype*()
.hasQualifiedName(guavaCollectPackage(), "ImmutableCollection") and
// public ImmutableList<E> asList()
this.hasName("asList")
}
override predicate returnsTaintFrom(int arg) { arg = -1 }
}
/**
* A taint-preserving static method of `com.google.common.collect.Sets`.
*/
private class SetsMethod extends TaintPreservingCallable {
int arg;
SetsMethod() {
this.getDeclaringType().hasQualifiedName(guavaCollectPackage(), "Sets") and
this.isStatic() and
(
// static <E> HashSet<E> newHashSet(E... elements)
// static <E> Set<E> newConcurrentHashSet(Iterable<? extends E> elements)
// static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet(Iterable<? extends E> elements)
// etc
this.getName().matches("new%Set") and
arg = 0
or
// static <B> Set<List<B>> cartesianProduct(List<? extends Set<? extends B>> sets)
// static <B> Set<List<B>> cartesianProduct(Set<? extends B>... sets)
// static <E> Set<Set<E>> combinations(Set<E> set, int size)
// static <E> Sets.SetView<E> difference(Set<E> set1, Set<?> set2)
// static <E> NavigableSet<E> filter(NavigableSet<E> unfiltered, Predicate<? super E> predicate)
// static <E> Set<E> filter(Set<E> unfiltered, Predicate<? super E> predicate)
// static <E> SortedSet<E> filter(SortedSet<E> unfiltered, Predicate<? super E> predicate)
// static <E> Set<Set<E>> powerSet(Set<E> set)
// static <K extends Comparable<? super K>> NavigableSet<K> subSet(NavigableSet<K> set, Range<K> range)
// static <E> NavigableSet<E> synchronizedNavigableSet(NavigableSet<E> navigableSet)
// static <E> NavigableSet<E> unmodifiableNavigableSet(NavigableSet<E> set)
this.hasName([
"cartesianProduct", "combinations", "difference", "filter", "powerSet", "subSet",
"synchronizedNavigableSet", "unmodifyableNavigableSet"
]) and
arg = 0
or
// static <E> Sets.SetView<E> symmetricDifference(Set<? extends E> set1, Set<? extends E> set2)
// static <E> Sets.SetView<E> union(Set<? extends E> set1, Set<? extends E> set2)
this.hasName(["symmetricDifference", "union"]) and
arg = [0, 1]
)
}
override predicate returnsTaintFrom(int arg_) { arg_ = arg }
}

View File

@@ -0,0 +1,9 @@
/**
* Definitions for tracking taint steps through the Guava framework.
*/
import java
import Base
import Collections
import IO
import Cache

View File

@@ -0,0 +1,102 @@
/** Definitions of taint steps in the IO package of the Guava framework */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class GuavaIoCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
"com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;withSeparator;(String,int);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;upperCase;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;lowerCase;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;withPadChar;(char);;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;omitPadding;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;asCharSource;(Charset);;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;concat;(ByteSource[]);;ArrayElement of Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;concat;(Iterable);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;concat;(Iterator);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;copyTo;(OutputStream);;Argument[-1];Argument[0];taint",
"com.google.common.io;ByteSource;true;openStream;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;read;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;slice;(long,long);;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;wrap;(byte[]);;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteStreams;false;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint",
"com.google.common.io;ByteStreams;false;copy;(ReadablyByteChannel,WritableByteChannel);;Argument[0];Argument[1];taint",
"com.google.common.io;ByteStreams;false;limit;(InputStream,long);;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteStreams;false;newDataInput;(byte[]);;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteStreams;false;newDataInput;(byte[],int);;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteStreams;false;newDataInput;(ByteArrayInputStream);;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteStreams;false;newDataOutput;(ByteArrayOutputStream);;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteStreams;false;read;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
"com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint",
"com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
"com.google.common.io;ByteStreams;false;toByteArray;(InputStream);;Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;(CharSource[]);;ArrayElement of Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;(Iterable);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;(Iterator);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;copyTo;(Appendable);;Argument[-1];Argument[0];taint",
"com.google.common.io;CharSource;true;openStream;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;read;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;readFirstLine;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;readLines;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;lines;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;wrap;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.io;CharStreams;false;copy;(Readable,Appendable);;Argument[0];Argument[1];taint",
"com.google.common.io;CharStreams;false;readLines;(Readable);;Argument[0];ReturnValue;taint",
"com.google.common.io;CharStreams;false;toString;(Readable);;Argument[0];ReturnValue;taint",
"com.google.common.io;Closer;true;register;;;Argument[0];ReturnValue;value",
"com.google.common.io;Files;false;getFileExtension;(String);;Argument[0];ReturnValue;taint",
"com.google.common.io;Files;false;getNameWithoutExtension;(String);;Argument[0];ReturnValue;taint",
"com.google.common.io;Files;false;simplifyPath;(String);;Argument[0];ReturnValue;taint",
"com.google.common.io;MoreFiles;false;getFileExtension;(Path);;Argument[0];ReturnValue;taint",
"com.google.common.io;MoreFiles;false;getNameWithoutExtension;(Path);;Argument[0];ReturnValue;taint",
"com.google.common.io;LineReader;false;LineReader;(Readable);;Argument[0];Argument[-1];taint",
"com.google.common.io;LineReader;true;readLine;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteArrayDataOutput;true;toByteArray;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteArrayDataOutput;true;write;(byte[]);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;write;(byte[],int,int);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;write;(int);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeByte;(int);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeBytes;(String);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeChar;(int);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeChars;(String);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeDouble;(double);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeFloat;(float);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeInt;(int);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeLong;(long);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeShort;(int);;Argument[0];Argument[-1];taint",
"com.google.common.io;ByteArrayDataOutput;true;writeUTF;(String);;Argument[0];Argument[-1];taint"
]
}
}
private class GuavaIoSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//`namespace; type; subtypes; name; signature; ext; input; kind`
"com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;asCharSource;(URL,Charset);;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;copy;(URL,OutputStream);;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;readLines;;;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;toByteArray;(URL);;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;toString;(URL,Charset);;Argument[0];url-open-stream"
]
}
}