misc. hardening and bug fixes

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3329 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2009-03-17 16:01:43 +00:00
parent 901438ecb5
commit d175c8e0e3
13 changed files with 155 additions and 107 deletions

View File

@ -42,6 +42,12 @@ public class ExtractMatchingClasses {
}
String in = args[0];
String out = args[1];
if (in == null) {
throw new IllegalArgumentException("null args[0]");
}
if (out == null) {
throw new IllegalArgumentException("null args[1]");
}
String[] match = new String[args.length - 2];
System.arraycopy(args, 2, match, 0, match.length);

View File

@ -457,8 +457,7 @@ public abstract class ConstantInstruction extends Instruction {
}
/**
* @return the constant value pushed: an Integer, a Long, a Float, a Double, a
* String, or null
* @return the constant value pushed: an Integer, a Long, a Float, a Double, a String, or null
*/
public abstract Object getValue();
@ -478,17 +477,21 @@ public abstract class ConstantInstruction extends Instruction {
} else if (type.equals(TYPE_Class)) {
return makeClass((String) constant);
} else {
switch (Util.getTypeIndex(type)) {
case TYPE_int_index:
return make(((Number) constant).intValue());
case TYPE_long_index:
return make(((Number) constant).longValue());
case TYPE_float_index:
return make(((Number) constant).floatValue());
case TYPE_double_index:
return make(((Number) constant).doubleValue());
default:
throw new IllegalArgumentException("Invalid type for constant: " + type);
try {
switch (Util.getTypeIndex(type)) {
case TYPE_int_index:
return make(((Number) constant).intValue());
case TYPE_long_index:
return make(((Number) constant).longValue());
case TYPE_float_index:
return make(((Number) constant).floatValue());
case TYPE_double_index:
return make(((Number) constant).doubleValue());
default:
throw new IllegalArgumentException("Invalid type for constant: " + type);
}
} catch (ClassCastException e) {
throw new IllegalArgumentException(e);
}
}
}
@ -540,7 +543,22 @@ public abstract class ConstantInstruction extends Instruction {
final public boolean equals(Object o) {
if (o instanceof ConstantInstruction) {
ConstantInstruction i = (ConstantInstruction) o;
return i.getType().equals(getType()) && i.getValue().equals(getValue());
if (!i.getType().equals(getType())) {
return false;
}
if (i.getValue() == null) {
if (getValue() == null) {
return true;
} else {
return false;
}
} else {
if (getValue() == null) {
return false;
} else {
return i.getValue().equals(getValue());
}
}
} else {
return false;
}
@ -558,7 +576,8 @@ public abstract class ConstantInstruction extends Instruction {
@Override
final public int hashCode() {
return getType().hashCode() + 14411 * getValue().hashCode();
int v = getValue() == null ? 0 : getValue().hashCode();
return getType().hashCode() + 14411 * v;
}
@Override

View File

@ -10,18 +10,19 @@
*******************************************************************************/
package com.ibm.wala.shrikeBT;
import com.ibm.wala.annotations.NonNull;
/**
* This class represents instanceof instructions.
*/
public final class InstanceofInstruction extends Instruction {
@NonNull
final private String type;
protected InstanceofInstruction(String type) {
super(OP_instanceof);
this.type = type;
if (type == null) {
throw new IllegalArgumentException("null type");
}
}
public static InstanceofInstruction make(String type) {

View File

@ -129,6 +129,9 @@ public final class MethodEditor {
* instructions-to-bytecode-offsets map.
*/
public MethodEditor(Instruction[] instructions, ExceptionHandler[][] handlers, int[] instructionsToBytecodes) {
if (instructions == null) {
throw new IllegalArgumentException("null instructions");
}
methodInfo = null;
this.instructionsToBytecodes = instructionsToBytecodes;
this.instructions = instructions;

View File

@ -41,8 +41,8 @@ public final class Util {
* @throws IllegalArgumentException if s is null
*/
public static byte getWordSize(String s) {
if (s == null) {
throw new IllegalArgumentException("s is null");
if (s == null || s.length() == 0) {
throw new IllegalArgumentException("invalid s: " + s);
}
return getWordSize(s, 0);
}
@ -210,8 +210,8 @@ public final class Util {
* @throws IllegalArgumentException if type == null
*/
static int getParamsCount(String type) throws IllegalArgumentException {
if (type == null) {
throw new IllegalArgumentException("type == null");
if (type == null || type.length() < 2) {
throw new IllegalArgumentException("invalid type: " + type);
}
int index = 1;
int count = 0;
@ -289,8 +289,8 @@ public final class Util {
* @throws IllegalArgumentException if t is null
*/
public static String getStackType(String t) {
if (t == null) {
throw new IllegalArgumentException("t is null");
if (t == null || t.length() < 1) {
throw new IllegalArgumentException("invalid t: " + t);
}
switch (t.charAt(0)) {
case 'Z':
@ -330,7 +330,7 @@ public final class Util {
* @return true iff t is a primitive type
*/
public static boolean isPrimitiveType(String t) {
if (t == null) {
if (t == null || t.length() == 0) {
return false;
} else {
switch (t.charAt(0)) {

View File

@ -55,6 +55,9 @@ public class Analyzer {
protected final static int[] noEdges = new int[0];
public Analyzer(boolean isStatic, String classType, String signature, IInstruction[] instructions, ExceptionHandler[][] handlers) {
if (instructions == null) {
throw new IllegalArgumentException("null instructions");
}
this.classType = classType;
this.isStatic = isStatic;
this.signature = signature;

View File

@ -56,26 +56,26 @@ import com.ibm.wala.shrikeBT.Util;
* System.out.println(&quot;Verification failed at instruction &quot;
* + ex.getOffset() + &quot;: &quot; + ex.getReason());
* }
*
*
* </pre>
*
* For full verification you need to provide class hierarchy information using
* setClassHierarchy. Without this information, we can't compute the exact types
* of variables at control flow merge points. If you don't provide a hierarchy,
* or the hierarchy you provide is partial, then the Verifier will be
* optimistic.
* For full verification you need to provide class hierarchy information using setClassHierarchy. Without this information, we can't
* compute the exact types of variables at control flow merge points. If you don't provide a hierarchy, or the hierarchy you provide
* is partial, then the Verifier will be optimistic.
*
* This method can also be used to gather type information for every stack and
* local variable at every program point. Just call computeTypes() instead of
* verify() and then retrieve the results with getLocalTypes() and
* getStackTypes().
* This method can also be used to gather type information for every stack and local variable at every program point. Just call
* computeTypes() instead of verify() and then retrieve the results with getLocalTypes() and getStackTypes().
*/
public final class Verifier extends Analyzer {
final class VerifyVisitor extends TypeVisitor {
private int curIndex;
private List<PathElement> curPath;
private FailureException ex;
private String[] curStack;
private String[] curLocals;
VerifyVisitor() {
@ -293,18 +293,17 @@ public final class Verifier extends Analyzer {
/**
* Initialize a verifier.
* @throws NullPointerException if info is null
*
* @throws NullPointerException if info is null
*/
public Verifier(MethodData info) throws NullPointerException {
super(info);
}
/**
* Try to verify the method. If verification is unsuccessful, we throw an
* exception.
* Try to verify the method. If verification is unsuccessful, we throw an exception.
*
* @throws FailureException
* the method contains invalid bytecode
* @throws FailureException the method contains invalid bytecode
*/
public void verify() throws FailureException {
VerifyVisitor v = new VerifyVisitor();

View File

@ -182,6 +182,9 @@ public class AddSerialVersion {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
if (args[i] == null) {
throw new IllegalArgumentException("args[" + i + "] is null");
}
try {
byte[] data = Util.readFully(new FileInputStream(args[i]));
ClassReader r = new ClassReader(data);

View File

@ -55,6 +55,9 @@ public final class MethodOptimizer {
final static int[] noEdges = new int[0];
public MethodOptimizer(MethodData d, MethodEditor e) {
if (d == null) {
throw new IllegalArgumentException("null d");
}
this.data = d;
this.editor = e;
}

View File

@ -322,6 +322,9 @@ public abstract class OfflineInstrumenterBase {
for (int i = 0; i < args.length; i++) {
String a = args[i];
if (a == null) {
throw new IllegalArgumentException("args[" + i + "] is null");
}
if (a.equals("-o") && i + 1 < args.length) {
setOutputJar(new File(args[i + 1]));
i++;
@ -600,7 +603,7 @@ public abstract class OfflineInstrumenterBase {
/**
* Call this when you're done modifying classes.
*/
final public void close() throws IOException {
final public void close() throws IOException, IllegalStateException {
if (passUnmodifiedClasses) {
writeUnmodifiedClasses();
}

View File

@ -902,13 +902,14 @@ public final class ClassWriter implements ClassConstants {
if (buf == null) {
throw new IllegalArgumentException("buf is null");
}
if (offset >= buf.length) {
try {
buf[offset] = (byte) (v >> 24);
buf[offset + 1] = (byte) (v >> 16);
buf[offset + 2] = (byte) (v >> 8);
buf[offset + 3] = (byte) v;
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("illegal offset " + offset);
}
buf[offset] = (byte) (v >> 24);
buf[offset + 1] = (byte) (v >> 16);
buf[offset + 2] = (byte) (v >> 8);
buf[offset + 3] = (byte) v;
}
/**
@ -942,10 +943,14 @@ public final class ClassWriter implements ClassConstants {
if (buf == null) {
throw new IllegalArgumentException("buf is null");
}
if (offset + 1 >= buf.length) {
if (offset < 0 || offset + 1 >= buf.length) {
throw new IllegalArgumentException("buf is too short " + buf.length + " " + offset);
}
buf[offset] = (byte) (v >> 8);
buf[offset + 1] = (byte) v;
try {
buf[offset] = (byte) (v >> 8);
buf[offset + 1] = (byte) v;
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("invalid offset: " + offset);
}
}
}

View File

@ -19,6 +19,9 @@ public final class ConstantPoolParser implements ClassConstants {
private int[] cpOffsets;
private String[] cpItems;
// TODO: use JVM spec limit here?
private final static int MAX_CP_ITEMS = Integer.MAX_VALUE / 4;
/**
* @param bytes the raw class file data
@ -30,7 +33,7 @@ public final class ConstantPoolParser implements ClassConstants {
if (offset < 0) {
throw new IllegalArgumentException("invalid offset: " + offset);
}
if (itemCount < 0) {
if (itemCount < 0 || itemCount > MAX_CP_ITEMS) {
throw new IllegalArgumentException("invalid itemCount: " + itemCount);
}
parseConstantPool(offset, itemCount);

View File

@ -17,13 +17,15 @@ import java.util.Arrays;
*/
public final class LocalVariableTableWriter extends ClassWriter.Element {
final private int attrID;
private int[] rawTable = emptyTable;
private static final int[] emptyTable = new int[0];
/**
* Create a blank LocalVariableTable.
* @throws IllegalArgumentException if w is null
*
* @throws IllegalArgumentException if w is null
*/
public LocalVariableTableWriter(ClassWriter w) {
if (w == null) {
@ -33,12 +35,9 @@ public final class LocalVariableTableWriter extends ClassWriter.Element {
}
/**
* Set the raw local variable table values. Consider using
* LocalVariableTableWriter.makeRawTable to build the raw values.
* Set the raw local variable table values. Consider using LocalVariableTableWriter.makeRawTable to build the raw values.
*
* @param table
* the raw values, a flattened sequence of (startPC, length,
* nameIndex, typeIndex, var) tuples
* @param table the raw values, a flattened sequence of (startPC, length, nameIndex, typeIndex, var) tuples
*/
public void setRawTable(int[] table) {
if (table == null) {
@ -83,73 +82,74 @@ public final class LocalVariableTableWriter extends ClassWriter.Element {
/**
* Build a raw local variable table from a formatted variable map.
*
* @param varMap
* an array mapping bytecode offsets to a variable map for each
* offset; a variable map is a array of 2*localVars elements,
* containing a (nameIndex, typeIndex) for each local variable; the
* pair (0,0) indicates that there is no information about that local
* variable at that offset
* @throws IllegalArgumentException if varMap == null
* @param varMap an array mapping bytecode offsets to a variable map for each offset; a variable map is a array of 2*localVars
* elements, containing a (nameIndex, typeIndex) for each local variable; the pair (0,0) indicates that there is no
* information about that local variable at that offset
* @throws IllegalArgumentException if varMap == null
*/
public static int[] makeRawTable(int[][] varMap) throws IllegalArgumentException {
if (varMap == null) {
throw new IllegalArgumentException("varMap == null");
}
int varCount = 0;
for (int i = 0; i < varMap.length; i++) {
if (varMap[i] != null) {
varCount = Math.max(varCount, varMap[i].length);
try {
int varCount = 0;
for (int i = 0; i < varMap.length; i++) {
if (varMap[i] != null) {
varCount = Math.max(varCount, varMap[i].length);
}
}
}
varCount /= 2;
varCount /= 2;
int[] entries = new int[20];
int[] varEnd = new int[varCount];
Arrays.fill(varEnd, -1);
int[] lastVector = null;
int entryCount = 0;
for (int i = 0; i < varMap.length; i++) {
if (varMap[i] != lastVector) {
lastVector = varMap[i];
int[] entries = new int[20];
int[] varEnd = new int[varCount];
Arrays.fill(varEnd, -1);
int[] lastVector = null;
int entryCount = 0;
for (int i = 0; i < varMap.length; i++) {
if (varMap[i] != lastVector) {
lastVector = varMap[i];
if (lastVector != null) {
for (int k = 0; k < lastVector.length / 2; k++) {
if (lastVector[k * 2] > 0 && i >= varEnd[k]) {
int entryOffset = entryCount * 5;
entryCount++;
if (entryCount * 5 > entries.length) {
int[] newEntries = new int[entries.length * 2];
System.arraycopy(entries, 0, newEntries, 0, entries.length);
entries = newEntries;
}
int nameIndex = lastVector[k * 2];
int typeIndex = lastVector[k * 2 + 1];
int end = i + 1;
while (end < varMap.length) {
if (varMap[end] == null || k * 2 >= varMap[end].length || varMap[end][k * 2] != nameIndex
|| varMap[end][k * 2 + 1] != typeIndex) {
break;
if (lastVector != null) {
for (int k = 0; k < lastVector.length / 2; k++) {
if (lastVector[k * 2] > 0 && i >= varEnd[k]) {
int entryOffset = entryCount * 5;
entryCount++;
if (entryCount * 5 > entries.length) {
int[] newEntries = new int[entries.length * 2];
System.arraycopy(entries, 0, newEntries, 0, entries.length);
entries = newEntries;
}
end++;
int nameIndex = lastVector[k * 2];
int typeIndex = lastVector[k * 2 + 1];
int end = i + 1;
while (end < varMap.length) {
if (varMap[end] == null || k * 2 >= varMap[end].length || varMap[end][k * 2] != nameIndex
|| varMap[end][k * 2 + 1] != typeIndex) {
break;
}
end++;
}
varEnd[k] = end;
entries[entryOffset] = i;
entries[entryOffset + 1] = end - i;
entries[entryOffset + 2] = nameIndex;
entries[entryOffset + 3] = typeIndex;
entries[entryOffset + 4] = k;
}
varEnd[k] = end;
entries[entryOffset] = i;
entries[entryOffset + 1] = end - i;
entries[entryOffset + 2] = nameIndex;
entries[entryOffset + 3] = typeIndex;
entries[entryOffset + 4] = k;
}
}
}
}
}
if (entryCount == 0) {
return null;
} else {
int[] r = new int[entryCount * 5];
System.arraycopy(entries, 0, r, 0, r.length);
return r;
if (entryCount == 0) {
return null;
} else {
int[] r = new int[entryCount * 5];
System.arraycopy(entries, 0, r, 0, r.length);
return r;
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("malformed varMap");
}
}
}