Convert existing Guava models to CSV system

This commit is contained in:
Joe Farebrother
2021-03-05 16:30:52 +00:00
parent fbbec5d2b9
commit 980b2c1f4c
5 changed files with 48 additions and 199 deletions

View File

@@ -0,0 +1,41 @@
/** 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 =
[
//"package;type;overrides;name;signature;ext;inputspec;outputspec;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;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;;;Argument;ReturnValue;taint",
"com.google.common.base;Joiner;false;appendTo;;;Argument;Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;;;Argument[0];ReturnValue;value",
"com.google.common.base;Joiner;false;join;;;Argument;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;ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument;Argument[0];taint",
"com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[0];ReturnValue;value",
"com.google.common.base;Joiner$MapJoiner;false;join;;;Argument;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"
]
}
}

View File

@@ -3,7 +3,6 @@
*/
import java
import StringUtils
import Base
import Collections
import Preconditions
import IO

View File

@@ -1,23 +0,0 @@
/** Definitions of flow steps through the Preconditions class in the Guava framework. */
import java
private import semmle.code.java.dataflow.FlowSteps
/**
* The class `com.google.common.base.Preconditions`.
*/
class TypeGuavaPreconditions extends Class {
TypeGuavaPreconditions() { this.hasQualifiedName("com.google.common.base", "Preconditions") }
}
/**
* A method that returns its argumnets.
*/
private class GuavaPreconditionsMethod extends TaintPreservingCallable {
GuavaPreconditionsMethod() {
this.getDeclaringType() instanceof TypeGuavaPreconditions and
this.hasName("checkNotNull")
}
override predicate returnsTaintFrom(int src) { src = 0 }
}

View File

@@ -1,169 +0,0 @@
/** Definitions of flow steps through the various string utility functions in the Guava framework. */
import java
private import semmle.code.java.dataflow.FlowSteps
/**
* The class `com.google.common.base.Strings`.
*/
class TypeGuavaStrings extends Class {
TypeGuavaStrings() { this.hasQualifiedName("com.google.common.base", "Strings") }
}
/**
* The class `com.google.common.base.Joiner`.
*/
class TypeGuavaJoiner extends Class {
TypeGuavaJoiner() { this.hasQualifiedName("com.google.common.base", "Joiner") }
}
/**
* The nested class `Joiner.MapJoiner`.
*/
class TypeGuavaMapJoiner extends NestedClass {
TypeGuavaMapJoiner() {
this.getEnclosingType() instanceof TypeGuavaJoiner and
this.hasName("MapJoiner")
}
}
/**
* The class `com.google.common.base.Splitter`.
*/
class TypeGuavaSplitter extends Class {
TypeGuavaSplitter() { this.hasQualifiedName("com.google.common.base", "Splitter") }
}
/**
* The nested class `Splitter.MapSplitter`.
*/
class TypeGuavaMapSplitter extends NestedClass {
TypeGuavaMapSplitter() {
this.getEnclosingType() instanceof TypeGuavaSplitter and
this.hasName("MapSplitter")
}
}
/**
* A taint preserving method on `com.google.common.base.Strings`.
*/
private class GuavaStringsTaintPreservingMethod extends TaintPreservingCallable {
GuavaStringsTaintPreservingMethod() {
this.getDeclaringType() instanceof TypeGuavaStrings and
// static String emptyToNull(String string)
// static String nullToEmpty(String string)
// static String padStart(String string, int minLength, char padChar)
// static String padEnd(String string, int minLength, char padChar)
// static String repeat(String string, int count)
// static String lenientFormat(String template, Object ... args)
this.hasName(["emptyToNull", "nullToEmpty", "padStart", "padEnd", "repeat", "lenientFormat"])
}
override predicate returnsTaintFrom(int src) {
src = 0
or
this.hasName("lenientFormat") and
src = [0 .. getNumberOfParameters()]
}
}
/**
* A method of `Joiner` or `MapJoiner`.
*/
private class GuavaJoinerMethod extends Method {
GuavaJoinerMethod() {
this.getDeclaringType().getASourceSupertype*() instanceof TypeGuavaJoiner or
this.getDeclaringType().getASourceSupertype*() instanceof TypeGuavaMapJoiner
}
}
/**
* A method that builds a `Joiner` or `MapJoiner`.
*/
private class GuavaJoinerBuilderMethod extends GuavaJoinerMethod, TaintPreservingCallable {
GuavaJoinerBuilderMethod() {
// static Joiner on(char separator)
// static Joiner on(String separator)
// Joiner skipNulls()
// Joiner useForNull(String nullText)
// Joiner.MapJoiner withKeyValueSeparator(char keyValueSeparator)
// Joiner.MapJoiner withKeyValueSeparator(String keyValueSeparator)
// Joiner.MapJoiner useForNull(String nullText) [on MapJoiner]
this.hasName(["on", "skipNulls", "useForNull", "withKeyValueSeparator"])
}
override predicate returnsTaintFrom(int src) {
src = 0
or
src = -1 and not isStatic()
}
}
/**
* An `appendTo` method on `Joiner` or `MapJoiner`.
*/
private class GuavaJoinerAppendToMethod extends GuavaJoinerMethod, TaintPreservingCallable {
GuavaJoinerAppendToMethod() {
// <A extends Appendable> A appendTo(A appendable, Iterable<?> parts)
// <A extends Appendable> A appendTo(A appendable, Iterator<?> parts)
// <A extends Appendable> A appendTo(A appendable, Object[] parts)
// <A extends Appendable> A appendTo(A appendable, Object first, Object second, Object... rest)
// StringBuilder appendTo(StringBuilder builder, Iterable<?> parts)
// StringBuilder appendTo(StringBuilder builder, Iterator<?> parts)
// StringBuilder appendTo(StringBuilder builder, Object[] parts)
// StringBuilder appendTo(StringBuilder builder, Object first, Object second, Object... rest)
// <A extends Appendable> A appendTo(A appendable, Iterable<? extends Map.Entry<?,?>> entries) [on MapJoiner]
// <A extends Appendable> A appendTo(A appendable, Iterator<? extends Map.Entry<?,?>> parts)
// <A extends Appendable> A appendTo(A appendable, Map<?,?> map)
// StringBuilder appendTo(StringBuilder builder, Iterable<? extends Map.Entry<?,?>> entries)
// StringBuilder appendTo(StringBuilder builder, Iterator<? extends Map.Entry<?,?>> entries)
// StringBuilder appendTo(StringBuilder builder, Map<?,?> map)
this.hasName("appendTo")
}
override predicate transfersTaint(int src, int sink) {
src = [-1 .. getNumberOfParameters()] and
src != sink and
sink = 0
}
override predicate returnsTaintFrom(int src) { src = [-1 .. getNumberOfParameters()] }
}
/**
* A `join` method on `Joiner` or `MapJoiner`.
*/
private class GuavaJoinMethod extends GuavaJoinerMethod, TaintPreservingCallable {
GuavaJoinMethod() {
// String join(Iterable<?> parts)
// String join(Iterator<?> parts)
// String join(Object[] parts)
// String join(Object first, Object second, Object... rest)
// String join(Iterable<? extends Map.Entry<?,?>> entries) [on MapJoiner]
// String join(Iterator<? extends Map.Entry<?,?>> entries)
// String join(Map<?,?> map)
this.hasName("join")
}
override predicate returnsTaintFrom(int src) { src = [-1 .. getNumberOfParameters()] }
}
/**
* A method of `Splitter` or `MapSplitter` that splits its input string.
*/
private class GuavaSplitMethod extends TaintPreservingCallable {
GuavaSplitMethod() {
(
this.getDeclaringType() instanceof TypeGuavaSplitter
or
this.getDeclaringType() instanceof TypeGuavaMapSplitter
) and
// Iterable<String> split(CharSequence sequence)
// List<String> splitToList(CharSequence sequence)
// Stream<String> splitToStream(CharSequence sequence)
// Map<String,String> split(CharSequence sequence) [on MapSplitter]
this.hasName(["split", "splitToList", "splitToStream"])
}
override predicate returnsTaintFrom(int src) { src = 0 }
}

View File

@@ -1,12 +1,9 @@
import com.google.common.base.Strings;
import com.google.common.base.Splitter;
import com.google.common.base.Joiner;
package com.google.common.base;
import java.util.Map;
import java.util.HashMap;
class TestStrings {
class TestBase {
String taint() { return "tainted"; }
void sink(Object o) {}
@@ -59,4 +56,8 @@ class TestStrings {
m.put("k2", x);
sink(safeJoiner.withKeyValueSeparator("=").join(m)); // $numTaintFlow=1
}
void test4() {
sink(Preconditions.checkNotNull(taint())); // $numTaintFlow=1
}
}