Merge pull request #6174 from joefarebrother/guava-collections

Java: Model Guava collections package
This commit is contained in:
Chris Smowton
2021-09-23 09:13:24 +01:00
committed by GitHub
91 changed files with 11329 additions and 1090 deletions

View File

@@ -1,122 +0,0 @@
package com.google.common.collect;
import java.util.Map;
import java.util.SortedSet;
import java.util.SortedMap;
import java.util.Comparator;
class TestCollect {
String taint() { return "tainted"; }
void sink(Object o) {}
void test1() {
String x = taint();
ImmutableSet<String> xs = ImmutableSet.of(x, "y", "z");
sink(xs.asList()); // $numTaintFlow=1
ImmutableSet<String> ys = ImmutableSet.of("a", "b", "c");
sink(Sets.filter(Sets.union(xs, ys), y -> true)); // $numTaintFlow=1
sink(Sets.newHashSet("a", "b", "c", "d", x)); // $numTaintFlow=1
}
void test2() {
sink(ImmutableList.of(taint(), taint(), taint(), taint())); // $numTaintFlow=4
sink(ImmutableMap.of(taint(), taint(), taint(), taint())); // $numTaintFlow=2
sink(ImmutableMultimap.of(taint(), taint(), taint(), taint())); // $numTaintFlow=2
sink(ImmutableTable.of(taint(),taint(), taint())); // $numTaintFlow=1
}
void test3() {
String x = taint();
ImmutableList.Builder<String> b = ImmutableList.builder();
b.add("a");
sink(b);
b.add(x);
sink(b.build()); // $numTaintFlow=1
b = ImmutableList.builder();
b.add("a").add(x);
sink(b.build()); // $numTaintFlow=1
sink(ImmutableList.builder().add("a").add(x).build()); // $numTaintFlow=1
ImmutableMap.Builder<String, String> b2 = ImmutableMap.builder();
b2.put(x,"v");
sink(b2);
b2.put("k",x);
sink(b2.build()); // $numTaintFlow=1
}
void test4(Table<String, String, String> t1, Table<String, String, String> t2, Table<String, String, String> t3) {
String x = taint();
t1.put(x, "c", "v");
sink(t1);
t1.put("r", x, "v");
sink(t1);
t1.put("r", "c", x);
sink(t1); // $numTaintFlow=1
sink(t1.row("r")); // $numTaintFlow=1
t2.putAll(t1);
for (Table.Cell<String,String,String> c : t2.cellSet()) {
sink(c.getValue()); // $numTaintFlow=1
}
sink(t1.remove("r", "c")); // $numTaintFlow=1
t3.row("r").put("c", x);
sink(t3); // $ MISSING:numTaintFlow=1
}
void test4(Multimap<String, String> m1, Multimap<String, String> m2, Multimap<String, String> m3,
Multimap<String, String> m4, Multimap<String, String> m5){
String x = taint();
m1.put("k", x);
sink(m1); // $numTaintFlow=1
sink(m1.get("k")); // $numTaintFlow=1
m2.putAll("k", ImmutableList.of("a", x, "b"));
sink(m2); // $numTaintFlow=1
m3.putAll(m1);
sink(m3); // $numTaintFlow=1
m4.replaceValues("k", m1.replaceValues("k", ImmutableList.of("a")));
for (Map.Entry<String, String> e : m4.entries()) {
sink(e.getValue()); // $numTaintFlow=1
}
m5.asMap().get("k").add(x);
sink(m5); // $ MISSING:numTaintFlow=1
}
void test5(Comparator<String> comp, SortedSet<String> sorS, SortedMap<String, String> sorM) {
ImmutableSortedSet<String> s = ImmutableSortedSet.of(taint());
sink(s); // $numTaintFlow=1
sink(ImmutableSortedSet.copyOf(s)); // $numTaintFlow=1
sink(ImmutableSortedSet.copyOf(comp, s)); // $numTaintFlow=1
sorS.add(taint());
sink(ImmutableSortedSet.copyOfSorted(sorS)); // $ MISSING: numTaintFlow=1
sink(ImmutableList.sortedCopyOf(s)); // $numTaintFlow=1
sink(ImmutableList.sortedCopyOf(comp, s)); // $numTaintFlow=1
ImmutableSortedMap<String, String> m = ImmutableSortedMap.of("k", taint());
sink(m); // $numTaintFlow=1
sink(ImmutableSortedMap.copyOf(m)); // $numTaintFlow=1
sink(ImmutableSortedMap.copyOf(m, comp)); // $numTaintFlow=1
sorM.put("k", taint());
sink(ImmutableSortedMap.copyOfSorted(sorM)); // $ MISSING: numTaintFlow=1
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/guava-30.0

View File

@@ -0,0 +1,14 @@
import java
import TestUtilities.InlineFlowTest
class SummaryModelTest extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;inputspec;outputspec;kind",
"generatedtest;Test;false;newWithElementDefault;(Object);;Argument[0];Element of ReturnValue;value",
"generatedtest;Test;false;newWithMapKeyDefault;(Object);;Argument[0];MapKey of ReturnValue;value",
"generatedtest;Test;false;newWithMapValueDefault;(Object);;Argument[0];MapValue of ReturnValue;value"
]
}
}

View File

@@ -0,0 +1,161 @@
package com.google.common.collect;
import java.util.Collection;
import java.util.Map;
import java.util.SortedSet;
import java.util.SortedMap;
import java.util.Comparator;
class TestCollect {
String taint() { return "tainted"; }
void sink(Object o) {}
<T> T element(Collection<T> c) {
return c.iterator().next();
}
<K,V> K mapKey(Map<K,V> m) {
return element(m.keySet());
}
<K,V> V mapValue(Map<K,V> m) {
return element(m.values());
}
<K,V> K multimapKey(Multimap<K,V> m) {
return element(m.keySet());
}
<K,V> V multimapValue(Multimap<K,V> m) {
return element(m.values());
}
<R,C,V> R tableRow(Table<R,C,V> t) {
return element(t.rowKeySet());
}
<R,C,V> C tableColumn(Table<R,C,V> t) {
return element(t.columnKeySet());
}
<R,C,V> V tableValue(Table<R,C,V> t) {
return element(t.values());
}
void test1() {
String x = taint();
ImmutableSet<String> xs = ImmutableSet.of(x, "y", "z");
sink(element(xs.asList())); // $numValueFlow=1
ImmutableSet<String> ys = ImmutableSet.of("a", "b", "c");
sink(element(Sets.filter(Sets.union(xs, ys), y -> true))); // $numValueFlow=1
sink(element(Sets.newHashSet("a", "b", "c", "d", x))); // $numValueFlow=1
}
void test2() {
sink(element(ImmutableList.of(taint(), taint(), taint(), taint(),taint(), taint(), taint(), taint(),taint(), taint(), taint(), taint(),taint(), taint(), taint(), taint()))); // $numValueFlow=16
sink(element(ImmutableSet.of(taint(), taint(), taint(), taint(),taint(), taint(), taint(), taint(),taint(), taint(), taint(), taint(),taint(), taint(), taint(), taint()))); // $numValueFlow=16
sink(mapKey(ImmutableMap.of(taint(), taint(), taint(), taint()))); // $numValueFlow=2
sink(mapValue(ImmutableMap.of(taint(), taint(), taint(), taint()))); // $numValueFlow=2
sink(multimapKey(ImmutableMultimap.of(taint(), taint(), taint(), taint()))); // $numValueFlow=2
sink(multimapValue(ImmutableMultimap.of(taint(), taint(), taint(), taint()))); // $numValueFlow=2
sink(tableRow(ImmutableTable.of(taint(), taint(), taint()))); // $numValueFlow=1
sink(tableColumn(ImmutableTable.of(taint(), taint(), taint()))); // $numValueFlow=1
sink(tableValue(ImmutableTable.of(taint(), taint(), taint()))); // $numValueFlow=1
}
void test3() {
String x = taint();
ImmutableList.Builder<String> b = ImmutableList.builder();
b.add("a");
sink(b);
b.add(x);
sink(element(b.build())); // $numValueFlow=1
b = ImmutableList.builder();
b.add("a").add(x);
sink(element(b.build())); // $numValueFlow=1
sink(ImmutableList.builder().add("a").add(x).build().toArray()[0]); // $numValueFlow=1
ImmutableMap.Builder<String, String> b2 = ImmutableMap.builder();
b2.put(x,"v");
sink(mapKey(b2.build())); // $numValueFlow=1
b2.put("k",x);
sink(mapValue(b2.build())); // $numValueFlow=1
}
void test4(Table<String, String, String> t1, Table<String, String, String> t2, Table<String, String, String> t3) {
String x = taint();
t1.put(x, "c", "v");
sink(tableRow(t1)); // $numValueFlow=1
t1.put("r", x, "v");
sink(tableColumn(t1)); // $numValueFlow=1
t1.put("r", "c", x);
sink(tableValue(t1)); // $numValueFlow=1
sink(mapKey(t1.row("r"))); // $numValueFlow=1
sink(mapValue(t1.row("r"))); // $numValueFlow=1
t2.putAll(t1);
for (Table.Cell<String,String,String> c : t2.cellSet()) {
sink(c.getValue()); // $numValueFlow=1
}
sink(t1.remove("r", "c")); // $numValueFlow=1
t3.row("r").put("c", x);
sink(tableValue(t3)); // $ MISSING:numValueFlow=1 // depends on aliasing
}
void test5(Multimap<String, String> m1, Multimap<String, String> m2, Multimap<String, String> m3,
Multimap<String, String> m4, Multimap<String, String> m5){
String x = taint();
m1.put("k", x);
sink(multimapValue(m1)); // $numValueFlow=1
sink(element(m1.get("k"))); // $numValueFlow=1
m2.putAll("k", ImmutableList.of("a", x, "b"));
sink(multimapValue(m2)); // $numValueFlow=1
m3.putAll(m1);
sink(multimapValue(m3)); // $numValueFlow=1
m4.replaceValues("k", m1.replaceValues("k", ImmutableList.of("a")));
for (Map.Entry<String, String> e : m4.entries()) {
sink(e.getValue()); // $numValueFlow=1
}
m5.asMap().get("k").add(x);
sink(multimapValue(m5)); // $ MISSING:numValueFlow=1 // depends on aliasing
}
void test6(Comparator<String> comp, SortedSet<String> sorS, SortedMap<String, String> sorM) {
ImmutableSortedSet<String> s = ImmutableSortedSet.of(taint());
sink(element(s)); // $numValueFlow=1
sink(element(ImmutableSortedSet.copyOf(s))); // $numValueFlow=1
sink(element(ImmutableSortedSet.copyOf(comp, s))); // $numValueFlow=1
sorS.add(taint());
sink(element(ImmutableSortedSet.copyOfSorted(sorS))); // $numValueFlow=1
sink(element(ImmutableList.sortedCopyOf(s))); // $numValueFlow=1
sink(element(ImmutableList.sortedCopyOf(comp, s))); // $numValueFlow=1
ImmutableSortedMap<String, String> m = ImmutableSortedMap.of("k", taint());
sink(mapValue(m)); // $numValueFlow=1
sink(mapValue(ImmutableSortedMap.copyOf(m))); // $numValueFlow=1
sink(mapValue(ImmutableSortedMap.copyOf(m, comp))); // $numValueFlow=1
sorM.put("k", taint());
sink(mapValue(ImmutableSortedMap.copyOfSorted(sorM))); // $numValueFlow=1
}
}

View File

@@ -24,6 +24,8 @@ class ValueFlowConf extends DataFlow::Configuration {
override predicate isSink(DataFlow::Node n) {
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
}
override int fieldFlowBranchLimit() { result = 100 }
}
class HasFlowTest extends InlineExpectationsTest {

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/guava-30.0
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/guava-30.0