Eval4j: catch IndexOutOfBounds exceptions
This commit is contained in:
@@ -127,11 +127,21 @@ class JDIEval(
|
||||
}
|
||||
|
||||
override fun getArrayElement(array: Value, index: Value): Value {
|
||||
return array.array().getValue(index.int).asValue()
|
||||
try {
|
||||
return array.array().getValue(index.int).asValue()
|
||||
}
|
||||
catch (e: IndexOutOfBoundsException) {
|
||||
throwEvalException(ArrayIndexOutOfBoundsException(e.getMessage()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun setArrayElement(array: Value, index: Value, newValue: Value) {
|
||||
array.array().setValue(index.int, newValue.asJdiValue(vm, array.asmType.arrayElementType))
|
||||
try {
|
||||
return array.array().setValue(index.int, newValue.asJdiValue(vm, array.asmType.arrayElementType))
|
||||
}
|
||||
catch (e: IndexOutOfBoundsException) {
|
||||
throwEvalException(ArrayIndexOutOfBoundsException(e.getMessage()))
|
||||
}
|
||||
}
|
||||
|
||||
private fun findField(fieldDesc: FieldDescription): jdi.Field {
|
||||
@@ -277,7 +287,4 @@ fun <T> mayThrow(f: () -> T): T {
|
||||
catch (e: jdi.InvocationException) {
|
||||
throw ThrownFromEvaluatedCodeException(e.exception().asValue())
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throwBrokenCodeException(e)
|
||||
}
|
||||
}
|
||||
@@ -731,6 +731,54 @@ class TestData extends BaseTestData {
|
||||
static class Derived extends Base {}
|
||||
}
|
||||
|
||||
static boolean exceptionIndexOutOfBounds() {
|
||||
int[] ints = new int[1];
|
||||
try { int i = ints[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { ints[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
short[] shorts = new short[1];
|
||||
try { short s = shorts[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { shorts[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
char[] chars = new char[1];
|
||||
try { char c = chars[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { chars[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
byte[] bytes = new byte[1];
|
||||
try { byte b = bytes[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { bytes[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
long[] longs = new long[1];
|
||||
try { long l = longs[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { longs[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
double[] doubles = new double[1];
|
||||
try { double d = doubles[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { doubles[2] = 1.0; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
float[] floats = new float[1];
|
||||
try { float f = floats[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { floats[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
boolean[] booleans = new boolean[1];
|
||||
try { boolean bool = booleans[2];return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { booleans[2] = true; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
Object[] objects = new Object[1];
|
||||
try { Object o = objects[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
try { objects[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean indexOutOfBoundsForString() {
|
||||
String str = "";
|
||||
try { str.charAt(10); return false; } catch (IndexOutOfBoundsException e) { }
|
||||
try { str.substring(10); return false; } catch (IndexOutOfBoundsException e) { }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public TestData() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,21 +150,23 @@ object REFLECTION_EVAL : Eval {
|
||||
val elementType = if (asmType.getDimensions() == 1) asmType.getElementType() else Type.getType(asmType.getDescriptor().substring(1))
|
||||
val arr = array.obj().checkNull()
|
||||
val ind = index.int
|
||||
return when (elementType.getSort()) {
|
||||
Type.BOOLEAN -> boolean(JArray.getBoolean(arr, ind))
|
||||
Type.BYTE -> byte(JArray.getByte(arr, ind))
|
||||
Type.SHORT -> short(JArray.getShort(arr, ind))
|
||||
Type.CHAR -> char(JArray.getChar(arr, ind))
|
||||
Type.INT -> int(JArray.getInt(arr, ind))
|
||||
Type.LONG -> long(JArray.getLong(arr, ind))
|
||||
Type.FLOAT -> float(JArray.getFloat(arr, ind))
|
||||
Type.DOUBLE -> double(JArray.getDouble(arr, ind))
|
||||
Type.OBJECT,
|
||||
Type.ARRAY -> {
|
||||
val value = JArray.get(arr, ind)
|
||||
if (value == null) NULL_VALUE else ObjectValue(value, Type.getType(value.javaClass))
|
||||
return mayThrow {
|
||||
when (elementType.getSort()) {
|
||||
Type.BOOLEAN -> boolean(JArray.getBoolean(arr, ind))
|
||||
Type.BYTE -> byte(JArray.getByte(arr, ind))
|
||||
Type.SHORT -> short(JArray.getShort(arr, ind))
|
||||
Type.CHAR -> char(JArray.getChar(arr, ind))
|
||||
Type.INT -> int(JArray.getInt(arr, ind))
|
||||
Type.LONG -> long(JArray.getLong(arr, ind))
|
||||
Type.FLOAT -> float(JArray.getFloat(arr, ind))
|
||||
Type.DOUBLE -> double(JArray.getDouble(arr, ind))
|
||||
Type.OBJECT,
|
||||
Type.ARRAY -> {
|
||||
val value = JArray.get(arr, ind)
|
||||
if (value == null) NULL_VALUE else ObjectValue(value, Type.getType(value.javaClass))
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unsupported array element type: $elementType")
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unsupported array element type: $elementType")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,20 +178,22 @@ object REFLECTION_EVAL : Eval {
|
||||
return
|
||||
}
|
||||
val elementType = array.asmType.getElementType()
|
||||
when (elementType.getSort()) {
|
||||
Type.BOOLEAN -> JArray.setBoolean(arr, ind, newValue.boolean)
|
||||
Type.BYTE -> JArray.setByte(arr, ind, newValue.int.toByte())
|
||||
Type.SHORT -> JArray.setShort(arr, ind, newValue.int.toShort())
|
||||
Type.CHAR -> JArray.setChar(arr, ind, newValue.int.toChar())
|
||||
Type.INT -> JArray.setInt(arr, ind, newValue.int)
|
||||
Type.LONG -> JArray.setLong(arr, ind, newValue.long)
|
||||
Type.FLOAT -> JArray.setFloat(arr, ind, newValue.float)
|
||||
Type.DOUBLE -> JArray.setDouble(arr, ind, newValue.double)
|
||||
Type.OBJECT,
|
||||
Type.ARRAY -> {
|
||||
JArray.set(arr, ind, newValue.obj())
|
||||
mayThrow {
|
||||
when (elementType.getSort()) {
|
||||
Type.BOOLEAN -> JArray.setBoolean(arr, ind, newValue.boolean)
|
||||
Type.BYTE -> JArray.setByte(arr, ind, newValue.int.toByte())
|
||||
Type.SHORT -> JArray.setShort(arr, ind, newValue.int.toShort())
|
||||
Type.CHAR -> JArray.setChar(arr, ind, newValue.int.toChar())
|
||||
Type.INT -> JArray.setInt(arr, ind, newValue.int)
|
||||
Type.LONG -> JArray.setLong(arr, ind, newValue.long)
|
||||
Type.FLOAT -> JArray.setFloat(arr, ind, newValue.float)
|
||||
Type.DOUBLE -> JArray.setDouble(arr, ind, newValue.double)
|
||||
Type.OBJECT,
|
||||
Type.ARRAY -> {
|
||||
JArray.set(arr, ind, newValue.obj())
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unsupported array element type: $elementType")
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unsupported array element type: $elementType")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user