Merge pull request #4383 from joefarebrother/guava-strings

Java: Add modelling for Guava
This commit is contained in:
Joe Farebrother
2020-10-26 10:16:55 +00:00
committed by GitHub
12 changed files with 445 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
import com.google.common.base.Strings;
import com.google.common.base.Splitter;
import com.google.common.base.Joiner;
import java.util.Map;
import java.util.HashMap;
class Test {
String taint() { return "tainted"; }
void sink(Object o) {}
void test1() {
String x = taint();
sink(Strings.padStart(x, 10, ' '));
sink(Strings.padEnd(x, 10, ' '));
sink(Strings.repeat(x, 3));
sink(Strings.emptyToNull(Strings.nullToEmpty(x)));
sink(Strings.lenientFormat(x, 3));
sink(Strings.commonPrefix(x, "abc"));
sink(Strings.commonSuffix(x, "cde"));
sink(Strings.lenientFormat("%s = %s", x, 3));
}
void test2() {
String x = taint();
Splitter s = Splitter.on(x).omitEmptyStrings();
sink(s.split("x y z"));
sink(s.split(x));
sink(s.splitToList(x));
sink(s.withKeyValueSeparator("=").split("a=b"));
sink(s.withKeyValueSeparator("=").split(x));
}
void test3() {
String x = taint();
Joiner taintedJoiner = Joiner.on(x);
Joiner safeJoiner = Joiner.on(", ");
StringBuilder sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sink(taintedJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sink(safeJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, x, x));
Map<String, String> m = new HashMap<String, String>();
m.put("k", "v");
sink(safeJoiner.withKeyValueSeparator("=").join(m));
sink(safeJoiner.withKeyValueSeparator(x).join(m));
sink(taintedJoiner.useForNull("(null)").withKeyValueSeparator("=").join(m));
m.put("k2", x);
sink(safeJoiner.withKeyValueSeparator("=").join(m));
}
}

View File

@@ -0,0 +1,17 @@
| Test.java:15:20:15:26 | taint(...) | Test.java:17:14:17:41 | padStart(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:18:14:18:39 | padEnd(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:19:14:19:33 | repeat(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:20:14:20:56 | emptyToNull(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:21:14:21:40 | lenientFormat(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:24:14:24:51 | lenientFormat(...) |
| Test.java:28:20:28:26 | taint(...) | Test.java:32:14:32:23 | split(...) |
| Test.java:28:20:28:26 | taint(...) | Test.java:33:14:33:29 | splitToList(...) |
| Test.java:28:20:28:26 | taint(...) | Test.java:35:14:35:50 | split(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:46:14:46:54 | appendTo(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:47:14:47:26 | toString(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:48:14:48:51 | appendTo(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:49:14:49:26 | toString(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:52:14:52:42 | appendTo(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:57:14:57:56 | join(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:58:14:58:82 | join(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:60:14:60:58 | join(...) |

View File

@@ -0,0 +1,18 @@
import java
import semmle.code.java.dataflow.TaintTracking
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:guava" }
override predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getMethod().hasName("taint")
}
override predicate isSink(DataFlow::Node n) {
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
}
}
from DataFlow::Node src, DataFlow::Node sink, Conf conf
where conf.hasFlow(src, sink)
select src, sink

View File

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