Skip to content

Commit 17903c2

Browse files
committed
make sure we don't pass on host null when objects behind a jdwp id has been reclaimed
1 parent 41c544c commit 17903c2

File tree

1 file changed

+77
-65
lines changed
  • espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl

1 file changed

+77
-65
lines changed

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,13 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
10871087
if (tag == TagConstants.OBJECT) {
10881088
tag = context.getTag(field.getTypeAsString());
10891089
}
1090-
Object value = readValue(tag, input, context);
1091-
context.setStaticFieldValue(field, value);
1090+
try {
1091+
Object value = readValue(tag, input, context);
1092+
context.setStaticFieldValue(field, value);
1093+
} catch (MissingReferenceException e) {
1094+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
1095+
return new CommandResult(reply);
1096+
}
10921097
}
10931098
return new CommandResult(reply);
10941099
}
@@ -1149,7 +1154,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
11491154
Object[] args = new Object[arguments];
11501155
for (int i = 0; i < arguments; i++) {
11511156
byte valueKind = input.readByte();
1152-
args[i] = readValue(valueKind, input, context);
1157+
try {
1158+
args[i] = readValue(valueKind, input, context);
1159+
} catch (MissingReferenceException e) {
1160+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
1161+
return new CommandResult(reply);
1162+
}
11531163
}
11541164

11551165
int invocationOptions = input.readInt();
@@ -1232,7 +1242,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
12321242
// we leave room for the allocated object as the first arg
12331243
for (int i = 1; i < args.length; i++) {
12341244
byte valueKind = input.readByte();
1235-
args[i] = readValue(valueKind, input, context);
1245+
try {
1246+
args[i] = readValue(valueKind, input, context);
1247+
} catch (MissingReferenceException e) {
1248+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
1249+
return new CommandResult(reply);
1250+
}
12361251
}
12371252

12381253
int invocationOptions = input.readInt();
@@ -1336,7 +1351,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
13361351
Object[] args = new Object[arguments];
13371352
for (int i = 0; i < arguments; i++) {
13381353
byte valueKind = input.readByte();
1339-
args[i] = readValue(valueKind, input, context);
1354+
try {
1355+
args[i] = readValue(valueKind, input, context);
1356+
} catch (MissingReferenceException e) {
1357+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
1358+
return new CommandResult(reply);
1359+
}
13401360
}
13411361

13421362
int invocationOptions = input.readInt();
@@ -1664,7 +1684,13 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
16641684
if (tag == TagConstants.OBJECT) {
16651685
tag = context.getTag(field.getTypeAsString());
16661686
}
1667-
Object value = readValue(tag, input, context);
1687+
Object value;
1688+
try {
1689+
value = readValue(tag, input, context);
1690+
} catch (MissingReferenceException e) {
1691+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
1692+
return new CommandResult(reply);
1693+
}
16681694
field.setValue(object, value);
16691695
}
16701696
return new CommandResult(reply);
@@ -1790,7 +1816,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
17901816
args[0] = receiver;
17911817
for (int i = 1; i < args.length; i++) {
17921818
byte valueKind = input.readByte();
1793-
args[i] = readValue(valueKind, input, context);
1819+
try {
1820+
args[i] = readValue(valueKind, input, context);
1821+
} catch (MissingReferenceException e) {
1822+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
1823+
return new CommandResult(reply);
1824+
}
17941825
}
17951826

17961827
controller.fine(() -> "trying to invoke method: " + method.getNameAsString());
@@ -2386,7 +2417,14 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
23862417
return new CommandResult(reply);
23872418
}
23882419

2389-
Object returnValue = readValue(input, controller.getContext());
2420+
byte valueKind = input.readByte();
2421+
Object returnValue;
2422+
try {
2423+
returnValue = readValue(valueKind, input, controller.getContext());
2424+
} catch (MissingReferenceException e) {
2425+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
2426+
return new CommandResult(reply);
2427+
}
23902428
if (returnValue == Void.TYPE) {
23912429
// we have to use an Interop value, so simply use
23922430
// the NULL object, since it will be popped for void
@@ -2586,31 +2624,21 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
25862624

25872625
byte tag = context.getArrayComponentTag(array);
25882626

2589-
setArrayValues(context, input, index, values, array, tag);
2627+
try {
2628+
setArrayValues(context, input, index, values, array, tag);
2629+
} catch (MissingReferenceException e) {
2630+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
2631+
return new CommandResult(reply);
2632+
}
25902633
return new CommandResult(reply);
25912634
}
25922635

2593-
private static void setArrayValues(JDWPContext context, PacketStream input, int index, int values, Object array, byte tag) {
2636+
private static void setArrayValues(JDWPContext context, PacketStream input, int index, int values, Object array, byte tag) throws MissingReferenceException {
25942637
for (int i = index; i < index + values; i++) {
2595-
Object value = switch (tag) {
2596-
case TagConstants.BOOLEAN -> input.readBoolean();
2597-
case TagConstants.BYTE -> input.readByte();
2598-
case TagConstants.SHORT -> input.readShort();
2599-
case TagConstants.CHAR -> input.readChar();
2600-
case TagConstants.INT -> input.readInt();
2601-
case TagConstants.FLOAT -> input.readFloat();
2602-
case TagConstants.LONG -> input.readLong();
2603-
case TagConstants.DOUBLE -> input.readDouble();
2604-
case TagConstants.ARRAY,
2605-
TagConstants.STRING,
2606-
TagConstants.CLASS_LOADER,
2607-
TagConstants.CLASS_OBJECT,
2608-
TagConstants.THREAD,
2609-
TagConstants.THREAD_GROUP,
2610-
TagConstants.OBJECT ->
2611-
context.getIds().fromId((int) input.readLong());
2612-
default -> throw new RuntimeException("should not reach here: " + tag);
2613-
};
2638+
Object value = readValue(tag, input, context);
2639+
if (value == null) {
2640+
throw new MissingReferenceException();
2641+
}
26142642
context.setArrayValue(array, i, value);
26152643
}
26162644
}
@@ -2738,7 +2766,13 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
27382766
for (int i = 0; i < slots; i++) {
27392767
String identifier = input.readInt() + ""; // slot index
27402768
byte kind = input.readByte();
2741-
Object value = readValue(kind, input, context);
2769+
Object value;
2770+
try {
2771+
value = readValue(kind, input, context);
2772+
} catch (MissingReferenceException e) {
2773+
reply.errorCode(ErrorCodes.INVALID_OBJECT);
2774+
return new CommandResult(reply);
2775+
}
27422776
frame.setVariable(value, identifier);
27432777
}
27442778
return new CommandResult(reply);
@@ -2910,39 +2944,7 @@ static CommandResult createReply(Packet packet) {
29102944
}
29112945
}
29122946

2913-
private static Object readValue(byte valueKind, PacketStream input, JDWPContext context) {
2914-
switch (valueKind) {
2915-
case TagConstants.BOOLEAN:
2916-
return input.readBoolean();
2917-
case TagConstants.BYTE:
2918-
return input.readByte();
2919-
case TagConstants.SHORT:
2920-
return input.readShort();
2921-
case TagConstants.CHAR:
2922-
return input.readChar();
2923-
case TagConstants.INT:
2924-
return input.readInt();
2925-
case TagConstants.FLOAT:
2926-
return input.readFloat();
2927-
case TagConstants.LONG:
2928-
return input.readLong();
2929-
case TagConstants.DOUBLE:
2930-
return input.readDouble();
2931-
case TagConstants.STRING:
2932-
case TagConstants.ARRAY:
2933-
case TagConstants.OBJECT:
2934-
case TagConstants.THREAD:
2935-
case TagConstants.THREAD_GROUP:
2936-
case TagConstants.CLASS_LOADER:
2937-
case TagConstants.CLASS_OBJECT:
2938-
return context.getIds().fromId((int) input.readLong());
2939-
default:
2940-
throw new RuntimeException("Should not reach here!");
2941-
}
2942-
}
2943-
2944-
private static Object readValue(PacketStream input, JDWPContext context) {
2945-
byte valueKind = input.readByte();
2947+
private static Object readValue(byte valueKind, PacketStream input, JDWPContext context) throws MissingReferenceException {
29462948
switch (valueKind) {
29472949
case TagConstants.VOID:
29482950
return Void.TYPE;
@@ -2962,14 +2964,20 @@ private static Object readValue(PacketStream input, JDWPContext context) {
29622964
return input.readLong();
29632965
case TagConstants.DOUBLE:
29642966
return input.readDouble();
2965-
case TagConstants.ARRAY:
29662967
case TagConstants.STRING:
2968+
case TagConstants.ARRAY:
29672969
case TagConstants.OBJECT:
29682970
case TagConstants.THREAD:
29692971
case TagConstants.THREAD_GROUP:
29702972
case TagConstants.CLASS_LOADER:
29712973
case TagConstants.CLASS_OBJECT:
2972-
return context.getIds().fromId((int) input.readLong());
2974+
Object value = context.getIds().fromId((int) input.readLong());
2975+
if (value == null) {
2976+
// the object was garbage collected, so callers need to reply with
2977+
// INVALID_OBJECT
2978+
throw new MissingReferenceException();
2979+
}
2980+
return value;
29732981
default:
29742982
throw new RuntimeException("Should not reach here!");
29752983
}
@@ -3297,4 +3305,8 @@ private static Object verifyClassObject(long classObjectId, PacketStream reply,
32973305
}
32983306
return object;
32993307
}
3308+
3309+
private static class MissingReferenceException extends Exception {
3310+
static final long serialVersionUID = -2187514293129322348L;
3311+
}
33003312
}

0 commit comments

Comments
 (0)