/*
* 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.Arrays;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
public class TestUtil
{
public static final int UNTAINTED = 0;
public static final int FULLY_TAINTED = 1;
private final SafeRandom sr;
private final int defaultMax;
private final int p;
public TestUtil(int maxlen, SafeRandom sr, int p) {
this.defaultMax = maxlen;
this.sr = sr;
this.p = p;
}
public SafeRandom rand() { return sr; }
//[ifJava5+]
public String randString(int maxlen) {
int len = sr.nextInt(maxlen);
StringBuilder sb = new StringBuilder(len);
BitSet b = new BitSet();
if (sr.nextBoolean() && len == 0) len = 1;
for (int i = 0; i < len; i++) {
int c, clen;
boolean taint = sr.nextInt(p) == 0 && p > 0;
int oldlen = sb.length();
c = Character.MIN_CODE_POINT + sr.nextInt(
Character.MAX_CODE_POINT - Character.MIN_CODE_POINT);
sb.append(Character.toChars(c));
clen = Character.charCount(c);
for (int j = 0; j < clen; j++)
b.set(oldlen + j, taint);
}
return new String(sb.toString(), new Taint(b, sb.length()));
}
//[fiJava5+]
//[ifJava4]
public String randString(int maxlen) {
int len = sr.nextInt(maxlen);
StringBuffer sb = new StringBuffer(len);
BitSet b = new BitSet();
if (sr.nextBoolean() && len == 0) len = 1;
for (int i = 0; i < len; i++) {
boolean taint = sr.nextInt(p) == 0 && p > 0;
sb.append((char) sr.nextInt(0xffff + 1));
b.set(sb.length() - 1, taint);
}
return new String(sb.toString(), new Taint(b, sb.length()));
}
//[fiJava4]
public String randString() { return randString(defaultMax); }
public String[] randStringArray(int maxlen) {
List l = new ArrayList();
int len = sr.nextInt(maxlen);
while (len >= 0) {
String s = randString(len);
l.add(s);
len -= s.length();
}
return (String[]) l.toArray(new String[l.size()]);
}
public String[] randStringArray() { return randStringArray(defaultMax); }
public Map randMap(int maxlen) {
HashMap h = new HashMap();
int len = sr.nextInt(maxlen);
while (len >= 0) {
String key = randString(len);
String[] value = randStringArray(len);
len -= key.length();
for (int i = 0; i < value.length; i++)
len -= value[i].length();
h.put(key, value);
}
return h;
}
public Map randMap() { return randMap(defaultMax); }
public Hashtable randHashtable(int maxlen) {
Hashtable h = new Hashtable();
int len = sr.nextInt(maxlen);
while (len >= 0) {
String key = randString(len);
String[] value = randStringArray(len);
len -= key.length();
for (int i = 0; i < value.length; i++)
len -= value[i].length();
h.put(key, value);
}
return h;
}
public Hashtable randHashtable() { return randHashtable(defaultMax); }
public boolean isValidTaintedString (String s, String taintS) {
if (!s.equals(taintS))
return false;
Taint t = s.@internal@taint();
if (t == null)
t = new Taint(false, s.length());
Taint tt = taintS.@internal@taint();
if (tt == null)
tt = new Taint(false, taintS.length());
for (int i = 0; i < taintS.length(); i++) {
if ((p == UNTAINTED && t.get(i))
|| (p == FULLY_TAINTED && !t.get(i)))
return false;
if (!tt.get(i))
return false;
}
return true;
}
public boolean isValidTaintedStringArray(String[] s, String[] taintS) {
if (taintS.length != s.length)
return false;
for (int i = 0; i < taintS.length; i++)
if (!isValidTaintedString(s[i], taintS[i]))
return false;
return true;
}
public boolean isValidTaintedMap(Map m, Map taintM) {
Set entries = m.entrySet();
Set taintEntries = taintM.entrySet();
Map.Entry[] e;
Map.Entry[] taintE;
e = (Map.Entry[]) entries.toArray(new Map.Entry[entries.size()]);
taintE = (Map.Entry[])
taintEntries.toArray(new Map.Entry[taintEntries.size()]);
if (e.length != taintE.length)
return false;
for (int i = 0; i < e.length; i++) {
String s = (String) e[i].getKey();
String[] sa = (String []) e[i].getValue();
boolean found = false;
for (int j = 0; j < taintE.length; j++) {
String taintS = (String) taintE[j].getKey();
if (taintS.equals(s)) {
if (!isValidTaintedString(s, taintS))
return false;
found = true;
break;
}
}
if (!found)
return false;
found = false;
for (int j = 0; j < taintE.length; j++) {
String[] taintSa = (String[]) taintE[j].getValue();
if (Arrays.equals(sa, taintSa)) {
if (!isValidTaintedStringArray(sa, taintSa))
return false;
found = true;
break;
}
}
if (!found)
return false;
}
return true;
}
public boolean isValidTaintedHashtable(Hashtable h, Hashtable taintH)
{
Set entries = h.entrySet();
Set taintEntries = taintH.entrySet();
Map.Entry[] e;
Map.Entry[] taintE;
e = (Map.Entry[]) entries.toArray(new Map.Entry[entries.size()]);
taintE = (Map.Entry[])
taintEntries.toArray(new Map.Entry[taintEntries.size()]);
if (e.length != taintE.length)
return false;
for (int i = 0; i < e.length; i++) {
String s = (String) e[i].getKey();
String[] sa = (String []) e[i].getValue();
boolean found = false;
for (int j = 0; j < taintE.length; j++) {
String taintS = (String) taintE[j].getKey();
if (taintS.equals(s)) {
if (!isValidTaintedString(s, taintS))
return false;
found = true;
break;
}
}
if (!found)
return false;
found = false;
for (int j = 0; j < taintE.length; j++) {
String[] taintSa = (String[]) taintE[j].getValue();
if (Arrays.equals(sa, taintSa)) {
if (!isValidTaintedStringArray(sa, taintSa))
return false;
found = true;
break;
}
}
if (!found)
return false;
}
return true;
}
public boolean isValidTaintedEnumeration(Enumeration e, Enumeration taintE)
{
while (e.hasMoreElements()) {
String s, taintS;
if (!taintE.hasMoreElements())
return false;
s = (String) e.nextElement();
taintS = (String) taintE.nextElement();
if (!isValidTaintedString(s, taintS))
return false;
}
if (taintE.hasMoreElements())
return false;
return true;
}
}