/*
* Copyright 2009-2012 Michael Dalton
*
* 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 jtaint;
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.Arrays;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public final class TaintTest extends Thread
{
private static int maxtlen = 65536 * 2;
private static int nrtest = 1024 * 32;
private static List taintList;
private static volatile boolean fail;
private Random r;
/* Enums exist only in JDK >= 1.5, so we do this the hard way */
static final class TaintMethod
{
public static final int T_CLONE = 0;
public static final int T_NEW = 1;
public static final int T_SETLENGTH = 2;
public static final int T_SET = 3;
public static final int T_CLEAR = 4;
public static final int T_GET = 5;
public static final int T_SUBSET = 6;
public static final int T_DELETE = 7;
public static final int T_APPEND = 8;
public static final int T_INSERT = 9;
public static final int T_REVERSE = 10;
public static final int T_ISTAINTED = 11;
public static final int T_CARDINALITY = 12;
public static final int T_SETRANGE = 13;
public static final int T_CLEARRANGE = 14;
public static final int T_ASBITSET = 15;
public static final int T_GETCHARS = 16;
public static final int T_INSERTUNTAINTED = 17;
public static final int T_END = 18;
public static final String[] methodNames = {
"clone",
"new",
"setLength",
"set",
"clear",
"get",
"subset",
"delete",
"append",
"insert",
"reverse",
"isTainted",
"cardinality",
"set(range)",
"clear(range)",
"asBitSet",
"getTaintAsChars",
"insertUntainted"
};
}
static final class TaintElem
{
/* If we ever declare taintList to be a ConcurrentQueue or other
* non-synchronized, thread-safe data structure, mark all these
* fields final and declare opList as a ConcurrentQueue
*/
Taint t;
SafeTaint st;
List opList;
int id;
public TaintElem(Taint t, SafeTaint st, int id) {
this.t = t;
this.st = st;
this.opList = new ArrayList();
this.id = id;
}
public Taint getTaint() { return t; }
public SafeTaint getSafeTaint() { return st; }
public void addOp(int op) { opList.add(TaintMethod.methodNames[op]); }
public void verify(Taint vt) throws IllegalArgumentException {
if (!st.verify(vt))
throw new IllegalArgumentException(this.toString());
}
public void verify(TaintElem otherte) throws IllegalArgumentException {
SafeTaint otherst = otherte.getSafeTaint();
if (!st.verify(t) || !st.verify(otherte.getTaint()) ||
!otherst.verify(otherte.getTaint()) || !otherst.verify(t))
throw new IllegalArgumentException(this.toString());
}
public void verify() throws IllegalArgumentException {
verify(t);
}
public String toString() {
String s = "id " + id + " taint " + t.toString() + " safetaint " +
st.toString() + " operations: ";
for (int i = 0; i < opList.size(); i++)
s += (String) opList.get(i);
return s;
}
}
public TaintTest(Random r) {
this.r = r;
}
private void testClone(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
SafeTaint newst = (SafeTaint) st.clone();
Taint newt = (Taint) t.clone();
TaintElem newte = new TaintElem(newt, newst, r.nextInt());
te.verify(newte);
newte.verify();
newte.addOp(TaintMethod.T_CLONE);
taintList.add(newte);
}
private void testNew() throws IllegalArgumentException {
Taint t;
SafeTaint st;
TaintElem te;
int len = r.nextInt(maxtlen);
boolean b[] = new boolean[len];
BitSet bs = new BitSet();
char[] c = new char[(len+15)/16];
/* Initialize booleans...*/
for (int i = 0; i < len; i++)
b[i] = r.nextBoolean();
/* ... and convert to BitSet */
for (int i = 0; i < len; i++)
if (b[i]) bs.set(i);
/* ... and finally to char[] */
for (int i = 0; i < len; i++)
if (b[i])
c[i/16] |= 1 << (i & 15);
switch(r.nextInt(4))
{
/* Taint() */
case 0:
t = new Taint();
if (len != 0)
t.setLength(len);
for (int i = 0; i < len; i++)
if (bs.get(i))
t.set(i);
break;
/* Taint(Bitset bs, int len) */
case 1:
t = new Taint(bs, len);
break;
/* Taint(boolean fill, int len */
case 2:
if (r.nextBoolean()) {
t = new Taint(true, len);
for (int i = 0; i < len; i++)
if (!b[i])
t.clear(i);
} else {
t = new Taint(false, len);
for (int i = 0; i < len; i++)
if (b[i])
t.set(i);
}
break;
/* Taint(char[] t, int len) */
case 3:
t = new Taint(c, len);
break;
default:
throw new RuntimeException("broken switch");
}
switch(r.nextInt(5))
{
/* SafeTaint() */
case 0:
st = new SafeTaint();
if (len != 0)
st.setLength(len);
for (int i = 0; i < len; i++)
if (bs.get(i))
st.set(i);
break;
/* SafeTaint(Bitset bs, int len) */
case 1:
st = new SafeTaint(bs, len);
break;
/* SafeTaint(boolean fill, int len */
case 2:
if (r.nextBoolean()) {
st = new SafeTaint(true, len);
for (int i = 0; i < len; i++)
if (!b[i])
st.clear(i);
} else {
st = new SafeTaint(false, len);
for (int i = 0; i < len; i++)
if (b[i])
st.set(i);
}
break;
/* SafeTaint(boolean[] b) */
case 3:
st = new SafeTaint(b);
break;
/* SafeTaint(char[] t, int len) */
case 4:
st = new SafeTaint(c, len);
break;
default:
throw new RuntimeException("broken switch");
}
te = new TaintElem(t, st, r.nextInt());
te.addOp(TaintMethod.T_NEW);
te.verify();
taintList.add(te);
}
private int randSafeIndex(TaintElem te)
{
SafeTaint st = te.getSafeTaint();
if (st.length() != 0)
return r.nextInt(st.length());
else
return 0;
}
private void testSetLength(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int len;
int m = maxtlen < st.length() ? st.length() + 1024 : maxtlen;
if (r.nextInt(16) == 0)
len = -r.nextInt(m);
else
len = r.nextInt(m);
if (len < 0) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.setLength(len);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.setLength(len);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
TaintElem tmp = new TaintElem(t.setLength(len),
st.setLength(len), r.nextInt());
te.verify(tmp);
if (t.length() != len || st.length() != len)
throw new IllegalArgumentException(te.toString());
}
}
private void testSet(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int index;
/* Potentially go out of bounds */
if (r.nextInt(16) == 0)
index = r.nextInt();
else
index = randSafeIndex(te);
if (index < 0 || index >= st.length()) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.set(index);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.set(index);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
t.set(index);
st.set(index);
TaintElem tmp = new TaintElem(t, st, r.nextInt());
te.verify(tmp);
if (!t.get(index) || !st.get(index))
throw new IllegalArgumentException(te.toString());
}
}
private void testGet(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int index;
/* Potentially go out of bounds */
if (r.nextInt(16) == 0)
index = r.nextInt();
else
index = randSafeIndex(te);
if (index < 0 || index >= st.length()) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.get(index);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.get(index);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
if (t.get(index) != st.get(index))
throw new IllegalArgumentException(te.toString());
}
}
private void testClear(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int index;
/* Potentially go out of bounds */
if (r.nextInt(16) == 0)
index = r.nextInt();
else
index = randSafeIndex(te);
if (index < 0 || index >= st.length()) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.clear(index);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.clear(index);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
t.clear(index);
st.clear(index);
TaintElem tmp = new TaintElem(t, st, r.nextInt());
te.verify(tmp);
if (t.get(index) || st.get(index))
throw new IllegalArgumentException(te.toString());
}
}
private void testDelete(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int beginIndex, endIndex;
if (r.nextInt(16) == 0) {
beginIndex = r.nextInt();
endIndex = r.nextInt();
} else {
beginIndex = randSafeIndex(te);
endIndex = randSafeIndex(te);
if (beginIndex > endIndex) {
int tmp = endIndex;
endIndex = beginIndex;
beginIndex = tmp;
}
}
if (beginIndex < 0 || beginIndex > endIndex ||
beginIndex > st.length()) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.delete(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.delete(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
int newlen;
if (endIndex > st.length())
endIndex = st.length();
newlen = st.length() - (endIndex - beginIndex);
SafeTaint oldst = (SafeTaint) st.clone();
TaintElem tmp = new TaintElem(t.delete(beginIndex, endIndex),
st.delete(beginIndex, endIndex), r.nextInt());
te.verify(tmp);
if (t.length() != newlen || st.length() != newlen)
throw new IllegalArgumentException(te.toString());
for (int i = 0; i < newlen; i++) {
int origidx;
if (i < beginIndex)
origidx = i;
else
origidx = i + (endIndex - beginIndex);
if (t.get(i) != st.get(i) || st.get(i) != oldst.get(origidx))
throw new IllegalArgumentException(te.toString());
}
}
}
private void testSubSet(TaintElem te) throws IllegalArgumentException {
int beginIndex, endIndex;
Taint t = te.getTaint(), subt;
SafeTaint st = te.getSafeTaint(), subst;
TaintElem subte;
if (r.nextInt(16) == 0) {
beginIndex = r.nextInt();
endIndex = r.nextInt();
} else {
beginIndex = randSafeIndex(te);
endIndex = randSafeIndex(te);
if (beginIndex > endIndex) {
int tmp = endIndex;
endIndex = beginIndex;
beginIndex = tmp;
}
}
if (beginIndex > endIndex || endIndex > st.length() ||
beginIndex < 0 || endIndex < 0) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
subt = t.subset(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
subst = st.subset(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
Taint oldt = (Taint) t.clone();
SafeTaint oldst = (SafeTaint) st.clone();
t.subset(beginIndex, endIndex);
st.subset(beginIndex, endIndex);
if (t.length() != endIndex-beginIndex ||
st.length() != endIndex-beginIndex)
throw new IllegalArgumentException(te.toString());
for (int i = beginIndex; i < endIndex; i++)
if (t.get(i-beginIndex) != st.get(i-beginIndex)
|| t.get(i-beginIndex) != oldt.get(i)
|| st.get(i-beginIndex) != oldst.get(i)
|| oldt.get(i) != oldst.get(i))
throw new IllegalArgumentException(te.toString());
}
}
private void testAppend(TaintElem te) throws IllegalArgumentException {
TaintElem otherte, tmp;
Taint t = te.getTaint(), othert;
SafeTaint st = te.getSafeTaint(), otherst, oldst;
int oldlen = st.length();
synchronized(taintList) {
if (taintList.size() == 0)
return;
otherte = (TaintElem) taintList.remove(r.nextInt(
taintList.size()));
}
othert = otherte.getTaint();
otherst = otherte.getSafeTaint();
oldst = (SafeTaint) st.clone();
tmp = new TaintElem(t.append(othert), st.append(otherst),
r.nextInt());
te.verify(tmp);
for (int i = 0; i < st.length(); i++) {
if (st.get(i) != t.get(i))
throw new IllegalArgumentException(te.toString());
if (i >= oldlen && (st.get(i) != otherst.get(i-oldlen) ||
t.get(i) != othert.get(i-oldlen)))
throw new IllegalArgumentException(te.toString());
}
taintList.add(otherte);
}
private void testInsert(TaintElem te) throws IllegalArgumentException {
int offset;
TaintElem otherte;
Taint t = te.getTaint(), othert;
SafeTaint st = te.getSafeTaint(), otherst;
int oldlen = st.length();
synchronized(taintList) {
if (taintList.size() == 0)
return;
otherte = (TaintElem) taintList.remove(r.nextInt(taintList.size()));
}
otherte.verify();
othert = otherte.getTaint();
otherst = otherte.getSafeTaint();
if (r.nextInt(16) == 0)
offset = r.nextInt();
else
offset = randSafeIndex(te);
if (offset < 0 || offset > st.length()) {
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.insert(offset,othert);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.insert(offset, otherst);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
TaintElem tmp = new TaintElem(t.insert(offset, othert),
st.insert(offset,otherst),
r.nextInt());
te.verify(tmp);
for (int i = 0; i < st.length(); i++) {
if (st.get(i) != t.get(i))
throw new IllegalArgumentException(te.toString());
if (i >= offset && i < offset + otherst.length() &&
st.get(i) != otherst.get(i-offset))
throw new IllegalArgumentException(te.toString());
}
}
taintList.add(otherte);
}
private void testInsertUntainted(TaintElem te)
throws IllegalArgumentException
{
int offset;
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int oldlen = st.length();
if (r.nextInt(16) == 0)
offset = r.nextInt();
else
offset = randSafeIndex(te);
int inslen = r.nextInt(1 + (st.length() >= maxtlen ? 32 : st.length()));
if (offset < 0 || offset > st.length()) {
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.insertUntainted(offset, inslen);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.insert(offset, new SafeTaint(false, inslen));
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
t.insertUntainted(offset, inslen);
st.insert(offset, new SafeTaint(false, inslen));
for (int i = 0; i < st.length(); i++)
if (st.get(i) != t.get(i))
throw new IllegalArgumentException(te.toString());
}
}
private void testReverse(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint(), oldst = (SafeTaint) st.clone();
TaintElem tmp = new TaintElem(t.reverse(), st.reverse(), r.nextInt());
te.verify(tmp);
if (st.length() != t.length() ||
st.length() != oldst.length())
throw new IllegalArgumentException(te.toString());
for (int i = 0; i < st.length(); i++)
if (st.get(i) != t.get(i) ||
st.get(i) != oldst.get(st.length() - 1 - i))
throw new IllegalArgumentException(te.toString());
}
private void testIsTainted(TaintElem te) {
if (te.getTaint().isTainted() != te.getSafeTaint().isTainted())
throw new IllegalArgumentException(te.toString());
}
private void testCardinality(TaintElem te) {
if (te.getTaint().cardinality() != te.getSafeTaint().cardinality())
throw new IllegalArgumentException(te.toString());
}
private void testSetRange(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int beginIndex, endIndex;
if (r.nextInt(16) == 0) {
beginIndex = r.nextInt();
endIndex = r.nextInt();
} else {
beginIndex = randSafeIndex(te);
endIndex = randSafeIndex(te);
if (beginIndex > endIndex) {
int tmp = endIndex;
endIndex = beginIndex;
beginIndex = tmp;
}
}
if (beginIndex > endIndex || endIndex >= st.length() ||
beginIndex < 0 || endIndex < 0) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.set(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.set(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
t.set(beginIndex, endIndex);
st.set(beginIndex, endIndex);
TaintElem tmp = new TaintElem(t, st, r.nextInt());
te.verify(tmp);
for (int i = beginIndex; i < endIndex; i++) {
if (!t.get(i) || !st.get(i))
throw new IllegalArgumentException(te.toString());
}
}
}
private void testClearRange(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int beginIndex, endIndex;
if (r.nextInt(16) == 0) {
beginIndex = r.nextInt();
endIndex = r.nextInt();
} else {
beginIndex = randSafeIndex(te);
endIndex = randSafeIndex(te);
if (beginIndex > endIndex) {
int tmp = endIndex;
endIndex = beginIndex;
beginIndex = tmp;
}
}
if (beginIndex > endIndex || endIndex >= st.length() ||
beginIndex < 0 || endIndex < 0) {
/* Fail deliberately */
SafeTaint oldst = (SafeTaint) st.clone();
boolean caught = false;
try {
t.clear(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught)
throw new IllegalArgumentException(te.toString());
caught = false;
try {
st.clear(beginIndex, endIndex);
} catch (IllegalArgumentException e) {
caught = true;
}
if (!caught || !oldst.verify(t))
throw new IllegalArgumentException(te.toString());
} else {
t.clear(beginIndex, endIndex);
st.clear(beginIndex, endIndex);
TaintElem tmp = new TaintElem(t, st, r.nextInt());
te.verify(tmp);
for (int i = beginIndex; i < endIndex; i++) {
if (t.get(i) || st.get(i))
throw new IllegalArgumentException(te.toString());
}
}
}
private void testAsBitSet(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
if (!st.asBitSet().equals(t.asBitSet()))
throw new IllegalArgumentException(te.toString());
}
private void testGetChars(TaintElem te) throws IllegalArgumentException {
Taint t = te.getTaint();
SafeTaint st = te.getSafeTaint();
int pad = r.nextInt(32);
char[] tchars = new char[pad + (t.length() + 15)/16];
char[] stchars = new char[pad + (st.length() + 15)/16];
int offset;
if (pad == 0)
offset = 0;
else
offset = r.nextInt(pad);
t.getTaintAsChars(tchars, offset);
st.getTaintAsChars(stchars, offset);
if (!Arrays.equals(tchars, stchars))
throw new IllegalArgumentException(te.toString());
}
public void test() throws IllegalArgumentException {
int op = r.nextInt(TaintMethod.T_END+1);
TaintElem te = null;
synchronized(taintList) {
if (taintList.size() < 3)
op = TaintMethod.T_NEW;
else
te = (TaintElem) taintList.remove(r.nextInt(taintList.size()));
}
if (op != TaintMethod.T_NEW) {
te.verify();
if (op != TaintMethod.T_END)
te.addOp(op);
}
switch(op)
{
case TaintMethod.T_CLONE:
testClone(te);
break;
case TaintMethod.T_NEW:
testNew();
break;
case TaintMethod.T_SETLENGTH:
testSetLength(te);
break;
case TaintMethod.T_SET:
testSet(te);
break;
case TaintMethod.T_GET:
testGet(te);
break;
case TaintMethod.T_CLEAR:
testClear(te);
break;
case TaintMethod.T_SUBSET:
testSubSet(te);
break;
case TaintMethod.T_DELETE:
testDelete(te);
break;
case TaintMethod.T_APPEND:
testAppend(te);
break;
case TaintMethod.T_INSERT:
testInsert(te);
break;
case TaintMethod.T_REVERSE:
testReverse(te);
break;
case TaintMethod.T_ISTAINTED:
testIsTainted(te);
break;
case TaintMethod.T_CARDINALITY:
testCardinality(te);
break;
case TaintMethod.T_SETRANGE:
testSetRange(te);
break;
case TaintMethod.T_CLEARRANGE:
testClearRange(te);
break;
case TaintMethod.T_ASBITSET:
testAsBitSet(te);
break;
case TaintMethod.T_GETCHARS:
testGetChars(te);
break;
case TaintMethod.T_INSERTUNTAINTED:
testInsertUntainted(te);
break;
case TaintMethod.T_END:
/* do nothing, re-insert original entry back into the list */
break;
default:
throw new RuntimeException("broken switch");
}
if (op != TaintMethod.T_NEW) {
/* Add te back to the list */
te.verify();
taintList.add(te);
}
}
public void run() {
try {
for (int i = 0; i < nrtest; i++)
test();
} catch (Throwable e) {
fail = true;
System.out.println(e);
e.printStackTrace();
}
}
public static void main(String[] args)
{
TaintTest[] t;
int ret = 0;
PrintStream ps = null;
Random[] randArray;
Random rbase;
String logfile = "TaintTest.log";
long seed = System.currentTimeMillis();
int threads = 1;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-s"))
seed = Long.decode(args[++i]).longValue();
else if (args[i].equals("-t"))
threads = Integer.decode(args[++i]).intValue();
else if (args[i].equals("-l"))
maxtlen = Integer.decode(args[++i]).intValue();
else if (args[i].equals("-n"))
nrtest = Integer.decode(args[++i]).intValue();
else if (args[i].equals("-f"))
logfile = args[++i];
else {
System.out.println("Usage: java TaintTest "
+ "[-t numberofTheads] [-s randomSeed] "
+ "[-l maximumLengthofTaint] "
+ "[-n NumberofTestsPerThread]"
+ "[-f logFileName]");
System.exit(-1);
}
}
try {
ps = new PrintStream(new FileOutputStream(logfile));
} catch (FileNotFoundException e) {
System.out.println("Error opening logfile [" + logfile + "]: " + e);
System.exit(-1);
}
ps.print("-s ");
ps.print(seed);
ps.print(" -t ");
ps.print(threads);
ps.print(" -l ");
ps.print(maxtlen);
ps.print(" -n ");
ps.print(nrtest);
ps.print(" -f ");
ps.print(logfile + "\n");
ps.flush();
ps.close();
/* else List l = new synchronedList(... ) */
taintList = new ArrayList();
t = new TaintTest[threads];
randArray = new Random[threads];
rbase = new Random(seed);
for (int i = 0; i < threads; i++)
randArray[i] = new Random(rbase.nextLong());
if (threads > 1)
taintList = Collections.synchronizedList(taintList);
for (int i = 0; i < threads; i++) {
t[i] = new TaintTest(randArray[i]);
t[i].start();
}
for (int i = 0; i < threads; i++) {
try {
t[i].join();
} catch (InterruptedException e) {
System.out.println("Interrupted!: " + e);
System.exit(-1);
}
}
if (fail)
ret = -1;
if (Log.hasError() || Log.hasWarning() || Log.hasVuln()) {
System.out.println("Error or Warning encountered -- check logs");
System.exit(-1);
}
System.exit(ret);
}
}