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:
parent
901438ecb5
commit
d175c8e0e3
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -56,26 +56,26 @@ import com.ibm.wala.shrikeBT.Util;
|
|||
* System.out.println("Verification failed at instruction "
|
||||
* + ex.getOffset() + ": " + 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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue