Skip to content

Commit d30d1a2

Browse files
Add unit tests and fix issues
1 parent c12f803 commit d30d1a2

File tree

7 files changed

+289
-8
lines changed

7 files changed

+289
-8
lines changed

java/ql/src/semmle/code/java/dataflow/ExternalFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ private import internal.DataFlowPrivate
7171
private module Frameworks {
7272
private import semmle.code.java.frameworks.ApacheHttp
7373
private import semmle.code.java.frameworks.apache.Lang
74+
private import semmle.code.java.frameworks.guava.Guava
7475
}
7576

7677
private predicate sourceModelCsv(string row) {

java/ql/src/semmle/code/java/frameworks/guava/Guava.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ import java
66
import StringUtils
77
import Collections
88
import Preconditions
9+
import IO

java/ql/src/semmle/code/java/frameworks/guava/IO.qll

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,54 @@ private class GuavaIoCsv extends SummaryModelCsv {
1414
"com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[0];ReturnValue;taint",
1515
"com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[0];ReturnValue;taint",
1616
"com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[0];ReturnValue;taint",
17-
"com.google.common.io;ByteSource;true;asCharSource;(Charset);;Argument[0];ReturnValue;taint",
17+
"com.google.common.io;BaseEncoding;true;withSeparator;(String,int);;Argument[0];ReturnValue;taint",
18+
"com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[-1];ReturnValue;taint",
19+
"com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[-1];ReturnValue;taint",
20+
"com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[-1];ReturnValue;taint",
21+
"com.google.common.io;BaseEncoding;true;encode;(byte[]);;Argument[-1];ReturnValue;taint",
22+
"com.google.common.io;BaseEncoding;true;upperCase;();;Argument[-1];ReturnValue;taint",
23+
"com.google.common.io;BaseEncoding;true;lowerCase;();;Argument[-1];ReturnValue;taint",
24+
"com.google.common.io;BaseEncoding;true;withPadChar;(char);;Argument[-1];ReturnValue;taint",
25+
"com.google.common.io;BaseEncoding;true;omitPadding;();;Argument[-1];ReturnValue;taint",
26+
"com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[-1];ReturnValue;taint",
27+
"com.google.common.io;ByteSource;true;asCharSource;(Charset);;Argument[-1];ReturnValue;taint",
1828
"com.google.common.io;ByteSource;true;concat;;;Argument[0];ReturnValue;taint",
1929
"com.google.common.io;ByteSource;true;openStream;();;Argument[-1];ReturnValue;taint",
2030
"com.google.common.io;ByteSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint",
2131
"com.google.common.io;ByteSource;true;read;();;Argument[-1];ReturnValue;taint",
2232
"com.google.common.io;ByteSource;true;slice;(long,long);;Argument[-1];ReturnValue;taint",
2333
"com.google.common.io;ByteSource;true;wrap;(byte[]);;Argument[0];ReturnValue;taint",
2434
"com.google.common.io;ByteStreams;false;copy;(InputStream,OutputStream);;Argument[0];Argument[1];taint",
35+
"com.google.common.io;ByteStreams;false;copy;(ReadablyByteChannel,WritableByteChannel);;Argument[0];Argument[1];taint",
2536
"com.google.common.io;ByteStreams;false;limit;(InputStream,long);;Argument[0];ReturnValue;taint",
2637
"com.google.common.io;ByteStreams;false;newDataInput;(byte[]);;Argument[0];ReturnValue;taint",
2738
"com.google.common.io;ByteStreams;false;newDataInput;(byte[],int);;Argument[0];ReturnValue;taint",
2839
"com.google.common.io;ByteStreams;false;newDataInput;(ByteArrayInputStream);;Argument[0];ReturnValue;taint",
29-
"com.google.common.io;ByteStreams;false;read;(InputStream,byte[],int,int);;Argument[0];Argument[-1];taint",
40+
"com.google.common.io;ByteStreams;false;read;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
3041
"com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint",
3142
"com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
3243
"com.google.common.io;ByteStreams;false;toByteArray;(InputStream);;Argument[0];ReturnValue;taint",
33-
"com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[0];ReturnValue;taint",
44+
"com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[-1];ReturnValue;taint",
3445
"com.google.common.io;CharSource;true;concat;;;Argument[0];ReturnValue;taint",
3546
"com.google.common.io;CharSource;true;copyTo;(Appendable);;Argument[-1];Argument[0];taint",
3647
"com.google.common.io;CharSource;true;openStream;();;Argument[-1];ReturnValue;taint",
3748
"com.google.common.io;CharSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint",
3849
"com.google.common.io;CharSource;true;read;();;Argument[-1];ReturnValue;taint",
3950
"com.google.common.io;CharSource;true;readFirstLine;();;Argument[-1];ReturnValue;taint",
4051
"com.google.common.io;CharSource;true;readLines;();;Argument[-1];ReturnValue;taint",
52+
"com.google.common.io;CharSource;true;lines;();;Argument[-1];ReturnValue;taint",
4153
"com.google.common.io;CharSource;true;wrap;(CharSequence);;Argument[0];ReturnValue;taint",
4254
"com.google.common.io;CharStreams;false;copy;(Readable,Appendable);;Argument[0];Argument[1];taint",
43-
"com.google.common.io;CharStreams;false;readLines;(Readable);;Argument[0];Argument[-1];taint",
55+
"com.google.common.io;CharStreams;false;readLines;(Readable);;Argument[0];ReturnValue;taint",
4456
"com.google.common.io;CharStreams;false;toString;(Readable);;Argument[0];ReturnValue;taint",
4557
"com.google.common.io;Closer;true;register;;;Argument[0];ReturnValue;value",
4658
"com.google.common.io;Files;false;getFileExtension;(String);;Argument[0];ReturnValue;taint",
4759
"com.google.common.io;Files;false;getNameWithoutExtension;(String);;Argument[0];ReturnValue;taint",
4860
"com.google.common.io;Files;false;simplifyPath;(String);;Argument[0];ReturnValue;taint",
4961
"com.google.common.io;MoreFiles;false;getFileExtension;(Path);;Argument[0];ReturnValue;taint",
5062
"com.google.common.io;MoreFiles;false;getNameWithoutExtension;(Path);;Argument[0];ReturnValue;taint",
51-
"com.google.common.io;LineReader;false;LineReader;(Reader);;Argument[0];ReturnValue;taint",
52-
"com.google.common.io;LineReader;false;readLine;();;Argument[-1];ReturnValue;taint"
63+
"com.google.common.io;LineReader;false;LineReader;(Readable);;Argument[0];ReturnValue;taint",
64+
"com.google.common.io;LineReader;true;readLine;();;Argument[-1];ReturnValue;taint"
5365
]
5466
}
5567
}

java/ql/test/library-tests/frameworks/guava/TestCollect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void test4(Table<String, String, String> t1, Table<String, String, String> t2, T
7272
sink(t1.remove("r", "c")); // $numTaintFlow=1
7373

7474
t3.row("r").put("c", x);
75-
sink(t3); // MISSING:$numTaintFlow=1
75+
sink(t3); // $ MISSING:numTaintFlow=1
7676
}
7777

7878
void test4(Multimap<String, String> m1, Multimap<String, String> m2, Multimap<String, String> m3,
@@ -94,7 +94,7 @@ void test4(Multimap<String, String> m1, Multimap<String, String> m2, Multimap<St
9494
}
9595

9696
m5.asMap().get("k").add(x);
97-
sink(m5); // MISSING:$numTaintFlow=1
97+
sink(m5); // $ MISSING:numTaintFlow=1
9898
}
9999

100100
void test5(Comparator<String> comp, SortedSet<String> sorS, SortedMap<String, String> sorM) {
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package com.google.common.io;
2+
3+
import com.google.common.collect.ImmutableList;
4+
import java.io.InputStreamReader;
5+
import java.io.Reader;
6+
import java.lang.StringBuffer;
7+
import java.io.ByteArrayInputStream;
8+
import java.io.InputStream;
9+
import java.io.Closeable;
10+
import java.nio.file.Path;
11+
import java.io.IOException;
12+
13+
class TestIO {
14+
Object taint() { return null; }
15+
String staint(){ return (String) taint(); }
16+
byte[] btaint() { return (byte[]) taint(); }
17+
InputStream itaint() { return (InputStream) taint(); }
18+
Reader rtaint() { return new InputStreamReader(itaint()); }
19+
Path ptaint() { return (Path) taint(); }
20+
21+
void sink(Object o) {}
22+
23+
void test1() {
24+
BaseEncoding enc = BaseEncoding.base64();
25+
sink(enc.decode(staint())); // $numTaintFlow=1
26+
sink(enc.encode(btaint())); // $numTaintFlow=1
27+
sink(enc.encode(btaint(), 0, 42)); // $numTaintFlow=1
28+
sink(enc.decodingStream(rtaint())); // $numTaintFlow=1
29+
sink(enc.decodingSource(CharSource.wrap(staint()))); // $numTaintFlow=1
30+
sink(enc.withSeparator(staint(), 10).omitPadding().lowerCase().decode("abc")); // $numTaintFlow=1
31+
}
32+
33+
void test2() throws IOException {
34+
ByteSource b = ByteSource.wrap(btaint());
35+
sink(b.openStream()); // $numTaintFlow=1
36+
sink(b.openBufferedStream()); // $numTaintFlow=1
37+
sink(b.asCharSource(null)); // $numTaintFlow=1
38+
sink(b.slice(42,1337)); // $numTaintFlow=1
39+
sink(b.read()); // $numTaintFlow=1
40+
sink(ByteSource.concat(ByteSource.empty(), ByteSource.empty(), b)); // $numTaintFlow=1
41+
sink(ByteSource.concat(ImmutableList.of(ByteSource.empty(), ByteSource.empty(), b))); // $numTaintFlow=1
42+
sink(b.read(new MyByteProcessor())); // $ MISSING:numTaintFlow=1
43+
44+
CharSource c = CharSource.wrap(staint());
45+
sink(c.openStream()); // $numTaintFlow=1
46+
sink(c.openBufferedStream()); // $numTaintFlow=1
47+
sink(c.asByteSource(null)); // $numTaintFlow=1
48+
sink(c.readFirstLine()); // $numTaintFlow=1
49+
sink(c.readLines()); // $numTaintFlow=1
50+
sink(c.read()); // $numTaintFlow=1
51+
sink(c.lines()); // $numTaintFlow=1
52+
sink(CharSource.concat(CharSource.empty(), CharSource.empty(), c)); // $numTaintFlow=1
53+
sink(CharSource.concat(ImmutableList.of(CharSource.empty(), CharSource.empty(), c))); // $numTaintFlow=1
54+
sink(c.readLines(new MyLineProcessor())); // $ MISSING:numTaintFlow=1
55+
c.forEachLine(l -> sink(l)); // $ MISSING:numTaintFlow=1
56+
StringBuffer buf = new StringBuffer();
57+
c.copyTo(buf);
58+
sink(buf); // $numTaintFlow=1
59+
}
60+
61+
class MyByteProcessor implements ByteProcessor<Object> {
62+
byte[] buf;
63+
public Object getResult() { return buf; }
64+
public boolean processBytes(byte[] b, int off, int len) { this.buf = b; return false; }
65+
}
66+
67+
class MyLineProcessor implements LineProcessor<String> {
68+
String s = "";
69+
public String getResult() { return s; }
70+
public boolean processLine(String l) { this.s += l; return true; }
71+
}
72+
73+
void test3() throws IOException {
74+
sink(ByteStreams.limit(itaint(), 1337)); // $numTaintFlow=1
75+
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
76+
sink(ByteStreams.newDataInput(btaint(), 0)); // $numTaintFlow=1
77+
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
78+
sink(ByteStreams.newDataInput(btaint()).readLine()); // $ MISSING:numTaintFlow=1
79+
sink(ByteStreams.newDataInput(new ByteArrayInputStream(btaint()))); // $numTaintFlow=1
80+
byte[] b1 = null, b2 = null, b3 = null;
81+
ByteStreams.read(itaint(), b1, 0, 42);
82+
sink(b1); // $numTaintFlow=1
83+
ByteStreams.readFully(itaint(), b2);
84+
sink(b2); // $numTaintFlow=1
85+
ByteStreams.readFully(itaint(), b3, 0, 42);
86+
sink(b3); // $numTaintFlow=1
87+
sink(ByteStreams.readBytes(itaint(), new MyByteProcessor())); // $ MISSING:numTaintFlow=1
88+
sink(ByteStreams.toByteArray(itaint())); // $numTaintFlow=1
89+
90+
StringBuffer buf = new StringBuffer();
91+
CharStreams.copy(rtaint(), buf);
92+
sink(buf); // $numTaintFlow=1
93+
sink(CharStreams.readLines(rtaint())); // $numTaintFlow=1
94+
sink(CharStreams.readLines(rtaint(), new MyLineProcessor())); // $ MISSING:numTaintFlow=1
95+
sink(CharStreams.toString(rtaint())); // $numTaintFlow=1
96+
}
97+
98+
void test4() throws IOException {
99+
sink(Closer.create().register((Closeable) taint())); // $numTaintFlow=1
100+
sink(new LineReader(rtaint()).readLine()); // $numTaintFlow=1
101+
sink(Files.simplifyPath(staint())); // $numTaintFlow=1
102+
sink(Files.getFileExtension(staint())); // $numTaintFlow=1
103+
sink(Files.getNameWithoutExtension(staint())); // $numTaintFlow=1
104+
sink(MoreFiles.getFileExtension(ptaint())); // $numTaintFlow=1
105+
sink(MoreFiles.getNameWithoutExtension(ptaint())); // $numTaintFlow=1
106+
}
107+
108+
void test6() throws IOException {
109+
sink(new CountingInputStream(itaint())); // $numTaintFlow=1
110+
byte[] buf = null;
111+
new CountingInputStream(itaint()).read(buf, 0, 42);
112+
sink(buf); // $numTaintFlow=1
113+
sink(new LittleEndianDataInputStream(itaint())); // $numTaintFlow=1
114+
sink(new LittleEndianDataInputStream(itaint()).readUTF()); // $ MISSING:numTaintFlow=1
115+
}
116+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (C) 2007 The Guava Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
package com.google.common.io;
16+
import java.io.FilterInputStream;
17+
import java.io.IOException;
18+
import java.io.InputStream;
19+
20+
public final class CountingInputStream extends FilterInputStream {
21+
public CountingInputStream(InputStream in) {
22+
super(in);
23+
}
24+
25+
public long getCount() {
26+
return 0;
27+
}
28+
29+
@Override
30+
public int read() throws IOException {
31+
return 0;
32+
}
33+
34+
@Override
35+
public int read(byte[] b, int off, int len) throws IOException {
36+
return 0;
37+
}
38+
39+
@Override
40+
public long skip(long n) throws IOException {
41+
return 0;
42+
}
43+
44+
@Override
45+
public synchronized void mark(int readlimit) {
46+
}
47+
48+
@Override
49+
public synchronized void reset() throws IOException {
50+
}
51+
52+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (C) 2007 The Guava Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
package com.google.common.io;
16+
import java.io.DataInput;
17+
import java.io.FilterInputStream;
18+
import java.io.IOException;
19+
import java.io.InputStream;
20+
21+
public final class LittleEndianDataInputStream extends FilterInputStream implements DataInput {
22+
public LittleEndianDataInputStream(InputStream in) {
23+
super(in);
24+
}
25+
26+
@Override
27+
public String readLine() {
28+
return null;
29+
}
30+
31+
@Override
32+
public void readFully(byte[] b) throws IOException {
33+
}
34+
35+
@Override
36+
public void readFully(byte[] b, int off, int len) throws IOException {
37+
}
38+
39+
@Override
40+
public int skipBytes(int n) throws IOException {
41+
return 0;
42+
}
43+
44+
@Override
45+
public int readUnsignedByte() throws IOException {
46+
return 0;
47+
}
48+
49+
@Override
50+
public int readUnsignedShort() throws IOException {
51+
return 0;
52+
}
53+
54+
@Override
55+
public int readInt() throws IOException {
56+
return 0;
57+
}
58+
59+
@Override
60+
public long readLong() throws IOException {
61+
return 0;
62+
}
63+
64+
@Override
65+
public float readFloat() throws IOException {
66+
return 0;
67+
}
68+
69+
@Override
70+
public double readDouble() throws IOException {
71+
return 0;
72+
}
73+
74+
@Override
75+
public String readUTF() throws IOException {
76+
return null;
77+
}
78+
79+
@Override
80+
public short readShort() throws IOException {
81+
return 0;
82+
}
83+
84+
@Override
85+
public char readChar() throws IOException {
86+
return '0';
87+
}
88+
89+
@Override
90+
public byte readByte() throws IOException {
91+
return 0;
92+
}
93+
94+
@Override
95+
public boolean readBoolean() throws IOException {
96+
return false;
97+
}
98+
99+
}

0 commit comments

Comments
 (0)