diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java index 9182b2d66..7e9ab4f7a 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java @@ -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); diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java index 378dd811a..7fe4f26a9 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java @@ -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 diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java index c2af623a0..33d92e02d 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java @@ -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) { diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java index b0c3c04f4..025a9d916 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java @@ -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; diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java index 6a70d619a..97fad7b66 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java @@ -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)) { diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java index 0eead4608..76f290411 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java @@ -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; diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java index c903f6c27..18e9e6d80 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java @@ -56,26 +56,26 @@ import com.ibm.wala.shrikeBT.Util; * System.out.println("Verification failed at instruction " * + ex.getOffset() + ": " + ex.getReason()); * } - * + * * * - * 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 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(); diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java index 269dcd037..cb9ea5cd3 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java @@ -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); diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java index 78584b5e0..b9498c92e 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java @@ -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; } diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java index d87b3a15b..793c9cada 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java @@ -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(); } diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java index d4fc25a50..806ef7770 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java @@ -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); + } } } \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java index e1483a5b1..c62c71d1c 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java @@ -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); diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java index 2d8726394..2ad52db5f 100644 --- a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java @@ -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"); } } } \ No newline at end of file