Add unit tests and fix issues

This commit is contained in:
Joe Farebrother
2021-03-02 17:12:48 +00:00
parent c12f8035c4
commit d30d1a2ab2
7 changed files with 289 additions and 8 deletions

View File

@@ -71,6 +71,7 @@ private import internal.DataFlowPrivate
private module Frameworks {
private import semmle.code.java.frameworks.ApacheHttp
private import semmle.code.java.frameworks.apache.Lang
private import semmle.code.java.frameworks.guava.Guava
}
private predicate sourceModelCsv(string row) {

View File

@@ -6,3 +6,4 @@ import java
import StringUtils
import Collections
import Preconditions
import IO

View File

@@ -14,7 +14,17 @@ private class GuavaIoCsv extends SummaryModelCsv {
"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;ByteSource;true;asCharSource;(Charset);;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;;;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;openStream;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint",
@@ -22,15 +32,16 @@ private class GuavaIoCsv extends SummaryModelCsv {
"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;read;(InputStream,byte[],int,int);;Argument[0];Argument[-1];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[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;;;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",
@@ -38,9 +49,10 @@ private class GuavaIoCsv extends SummaryModelCsv {
"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];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",
@@ -48,8 +60,8 @@ private class GuavaIoCsv extends SummaryModelCsv {
"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;(Reader);;Argument[0];ReturnValue;taint",
"com.google.common.io;LineReader;false;readLine;();;Argument[-1];ReturnValue;taint"
"com.google.common.io;LineReader;false;LineReader;(Readable);;Argument[0];ReturnValue;taint",
"com.google.common.io;LineReader;true;readLine;();;Argument[-1];ReturnValue;taint"
]
}
}

View File

@@ -72,7 +72,7 @@ class TestCollect {
sink(t1.remove("r", "c")); // $numTaintFlow=1
t3.row("r").put("c", x);
sink(t3); // MISSING:$numTaintFlow=1
sink(t3); // $ MISSING:numTaintFlow=1
}
void test4(Multimap<String, String> m1, Multimap<String, String> m2, Multimap<String, String> m3,
@@ -94,7 +94,7 @@ class TestCollect {
}
m5.asMap().get("k").add(x);
sink(m5); // MISSING:$numTaintFlow=1
sink(m5); // $ MISSING:numTaintFlow=1
}
void test5(Comparator<String> comp, SortedSet<String> sorS, SortedMap<String, String> sorM) {

View File

@@ -0,0 +1,116 @@
package com.google.common.io;
import com.google.common.collect.ImmutableList;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.StringBuffer;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Closeable;
import java.nio.file.Path;
import java.io.IOException;
class TestIO {
Object taint() { return null; }
String staint(){ return (String) taint(); }
byte[] btaint() { return (byte[]) taint(); }
InputStream itaint() { return (InputStream) taint(); }
Reader rtaint() { return new InputStreamReader(itaint()); }
Path ptaint() { return (Path) taint(); }
void sink(Object o) {}
void test1() {
BaseEncoding enc = BaseEncoding.base64();
sink(enc.decode(staint())); // $numTaintFlow=1
sink(enc.encode(btaint())); // $numTaintFlow=1
sink(enc.encode(btaint(), 0, 42)); // $numTaintFlow=1
sink(enc.decodingStream(rtaint())); // $numTaintFlow=1
sink(enc.decodingSource(CharSource.wrap(staint()))); // $numTaintFlow=1
sink(enc.withSeparator(staint(), 10).omitPadding().lowerCase().decode("abc")); // $numTaintFlow=1
}
void test2() throws IOException {
ByteSource b = ByteSource.wrap(btaint());
sink(b.openStream()); // $numTaintFlow=1
sink(b.openBufferedStream()); // $numTaintFlow=1
sink(b.asCharSource(null)); // $numTaintFlow=1
sink(b.slice(42,1337)); // $numTaintFlow=1
sink(b.read()); // $numTaintFlow=1
sink(ByteSource.concat(ByteSource.empty(), ByteSource.empty(), b)); // $numTaintFlow=1
sink(ByteSource.concat(ImmutableList.of(ByteSource.empty(), ByteSource.empty(), b))); // $numTaintFlow=1
sink(b.read(new MyByteProcessor())); // $ MISSING:numTaintFlow=1
CharSource c = CharSource.wrap(staint());
sink(c.openStream()); // $numTaintFlow=1
sink(c.openBufferedStream()); // $numTaintFlow=1
sink(c.asByteSource(null)); // $numTaintFlow=1
sink(c.readFirstLine()); // $numTaintFlow=1
sink(c.readLines()); // $numTaintFlow=1
sink(c.read()); // $numTaintFlow=1
sink(c.lines()); // $numTaintFlow=1
sink(CharSource.concat(CharSource.empty(), CharSource.empty(), c)); // $numTaintFlow=1
sink(CharSource.concat(ImmutableList.of(CharSource.empty(), CharSource.empty(), c))); // $numTaintFlow=1
sink(c.readLines(new MyLineProcessor())); // $ MISSING:numTaintFlow=1
c.forEachLine(l -> sink(l)); // $ MISSING:numTaintFlow=1
StringBuffer buf = new StringBuffer();
c.copyTo(buf);
sink(buf); // $numTaintFlow=1
}
class MyByteProcessor implements ByteProcessor<Object> {
byte[] buf;
public Object getResult() { return buf; }
public boolean processBytes(byte[] b, int off, int len) { this.buf = b; return false; }
}
class MyLineProcessor implements LineProcessor<String> {
String s = "";
public String getResult() { return s; }
public boolean processLine(String l) { this.s += l; return true; }
}
void test3() throws IOException {
sink(ByteStreams.limit(itaint(), 1337)); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint(), 0)); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint()).readLine()); // $ MISSING:numTaintFlow=1
sink(ByteStreams.newDataInput(new ByteArrayInputStream(btaint()))); // $numTaintFlow=1
byte[] b1 = null, b2 = null, b3 = null;
ByteStreams.read(itaint(), b1, 0, 42);
sink(b1); // $numTaintFlow=1
ByteStreams.readFully(itaint(), b2);
sink(b2); // $numTaintFlow=1
ByteStreams.readFully(itaint(), b3, 0, 42);
sink(b3); // $numTaintFlow=1
sink(ByteStreams.readBytes(itaint(), new MyByteProcessor())); // $ MISSING:numTaintFlow=1
sink(ByteStreams.toByteArray(itaint())); // $numTaintFlow=1
StringBuffer buf = new StringBuffer();
CharStreams.copy(rtaint(), buf);
sink(buf); // $numTaintFlow=1
sink(CharStreams.readLines(rtaint())); // $numTaintFlow=1
sink(CharStreams.readLines(rtaint(), new MyLineProcessor())); // $ MISSING:numTaintFlow=1
sink(CharStreams.toString(rtaint())); // $numTaintFlow=1
}
void test4() throws IOException {
sink(Closer.create().register((Closeable) taint())); // $numTaintFlow=1
sink(new LineReader(rtaint()).readLine()); // $numTaintFlow=1
sink(Files.simplifyPath(staint())); // $numTaintFlow=1
sink(Files.getFileExtension(staint())); // $numTaintFlow=1
sink(Files.getNameWithoutExtension(staint())); // $numTaintFlow=1
sink(MoreFiles.getFileExtension(ptaint())); // $numTaintFlow=1
sink(MoreFiles.getNameWithoutExtension(ptaint())); // $numTaintFlow=1
}
void test6() throws IOException {
sink(new CountingInputStream(itaint())); // $numTaintFlow=1
byte[] buf = null;
new CountingInputStream(itaint()).read(buf, 0, 42);
sink(buf); // $numTaintFlow=1
sink(new LittleEndianDataInputStream(itaint())); // $numTaintFlow=1
sink(new LittleEndianDataInputStream(itaint()).readUTF()); // $ MISSING:numTaintFlow=1
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.common.io;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public final class CountingInputStream extends FilterInputStream {
public CountingInputStream(InputStream in) {
super(in);
}
public long getCount() {
return 0;
}
@Override
public int read() throws IOException {
return 0;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return 0;
}
@Override
public long skip(long n) throws IOException {
return 0;
}
@Override
public synchronized void mark(int readlimit) {
}
@Override
public synchronized void reset() throws IOException {
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.common.io;
import java.io.DataInput;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public final class LittleEndianDataInputStream extends FilterInputStream implements DataInput {
public LittleEndianDataInputStream(InputStream in) {
super(in);
}
@Override
public String readLine() {
return null;
}
@Override
public void readFully(byte[] b) throws IOException {
}
@Override
public void readFully(byte[] b, int off, int len) throws IOException {
}
@Override
public int skipBytes(int n) throws IOException {
return 0;
}
@Override
public int readUnsignedByte() throws IOException {
return 0;
}
@Override
public int readUnsignedShort() throws IOException {
return 0;
}
@Override
public int readInt() throws IOException {
return 0;
}
@Override
public long readLong() throws IOException {
return 0;
}
@Override
public float readFloat() throws IOException {
return 0;
}
@Override
public double readDouble() throws IOException {
return 0;
}
@Override
public String readUTF() throws IOException {
return null;
}
@Override
public short readShort() throws IOException {
return 0;
}
@Override
public char readChar() throws IOException {
return '0';
}
@Override
public byte readByte() throws IOException {
return 0;
}
@Override
public boolean readBoolean() throws IOException {
return false;
}
}