Skip to content

[GR-63785] Avoid passing host null as method receiver and method arguments. #11092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1087,8 +1087,13 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
if (tag == TagConstants.OBJECT) {
tag = context.getTag(field.getTypeAsString());
}
Object value = readValue(tag, input, context);
context.setStaticFieldValue(field, value);
try {
Object value = readValue(tag, input, context);
context.setStaticFieldValue(field, value);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
}
return new CommandResult(reply);
}
Expand Down Expand Up @@ -1149,7 +1154,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
Object[] args = new Object[arguments];
for (int i = 0; i < arguments; i++) {
byte valueKind = input.readByte();
args[i] = readValue(valueKind, input, context);
try {
args[i] = readValue(valueKind, input, context);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
}

int invocationOptions = input.readInt();
Expand Down Expand Up @@ -1232,7 +1242,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
// we leave room for the allocated object as the first arg
for (int i = 1; i < args.length; i++) {
byte valueKind = input.readByte();
args[i] = readValue(valueKind, input, context);
try {
args[i] = readValue(valueKind, input, context);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
}

int invocationOptions = input.readInt();
Expand Down Expand Up @@ -1336,7 +1351,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
Object[] args = new Object[arguments];
for (int i = 0; i < arguments; i++) {
byte valueKind = input.readByte();
args[i] = readValue(valueKind, input, context);
try {
args[i] = readValue(valueKind, input, context);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
}

int invocationOptions = input.readInt();
Expand Down Expand Up @@ -1664,7 +1684,13 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
if (tag == TagConstants.OBJECT) {
tag = context.getTag(field.getTypeAsString());
}
Object value = readValue(tag, input, context);
Object value;
try {
value = readValue(tag, input, context);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
field.setValue(object, value);
}
return new CommandResult(reply);
Expand Down Expand Up @@ -1790,7 +1816,12 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
args[0] = receiver;
for (int i = 1; i < args.length; i++) {
byte valueKind = input.readByte();
args[i] = readValue(valueKind, input, context);
try {
args[i] = readValue(valueKind, input, context);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
}

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

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

byte tag = context.getArrayComponentTag(array);

setArrayValues(context, input, index, values, array, tag);
try {
setArrayValues(context, input, index, values, array, tag);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
return new CommandResult(reply);
}

private static void setArrayValues(JDWPContext context, PacketStream input, int index, int values, Object array, byte tag) {
private static void setArrayValues(JDWPContext context, PacketStream input, int index, int values, Object array, byte tag) throws MissingReferenceException {
for (int i = index; i < index + values; i++) {
Object value = switch (tag) {
case TagConstants.BOOLEAN -> input.readBoolean();
case TagConstants.BYTE -> input.readByte();
case TagConstants.SHORT -> input.readShort();
case TagConstants.CHAR -> input.readChar();
case TagConstants.INT -> input.readInt();
case TagConstants.FLOAT -> input.readFloat();
case TagConstants.LONG -> input.readLong();
case TagConstants.DOUBLE -> input.readDouble();
case TagConstants.ARRAY,
TagConstants.STRING,
TagConstants.CLASS_LOADER,
TagConstants.CLASS_OBJECT,
TagConstants.THREAD,
TagConstants.THREAD_GROUP,
TagConstants.OBJECT ->
context.getIds().fromId((int) input.readLong());
default -> throw new RuntimeException("should not reach here: " + tag);
};
Object value = readValue(tag, input, context);
if (value == null) {
throw new MissingReferenceException();
}
context.setArrayValue(array, i, value);
}
}
Expand Down Expand Up @@ -2738,7 +2766,13 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
for (int i = 0; i < slots; i++) {
String identifier = input.readInt() + ""; // slot index
byte kind = input.readByte();
Object value = readValue(kind, input, context);
Object value;
try {
value = readValue(kind, input, context);
} catch (MissingReferenceException e) {
reply.errorCode(ErrorCodes.INVALID_OBJECT);
return new CommandResult(reply);
}
frame.setVariable(value, identifier);
}
return new CommandResult(reply);
Expand Down Expand Up @@ -2910,39 +2944,7 @@ static CommandResult createReply(Packet packet) {
}
}

private static Object readValue(byte valueKind, PacketStream input, JDWPContext context) {
switch (valueKind) {
case TagConstants.BOOLEAN:
return input.readBoolean();
case TagConstants.BYTE:
return input.readByte();
case TagConstants.SHORT:
return input.readShort();
case TagConstants.CHAR:
return input.readChar();
case TagConstants.INT:
return input.readInt();
case TagConstants.FLOAT:
return input.readFloat();
case TagConstants.LONG:
return input.readLong();
case TagConstants.DOUBLE:
return input.readDouble();
case TagConstants.STRING:
case TagConstants.ARRAY:
case TagConstants.OBJECT:
case TagConstants.THREAD:
case TagConstants.THREAD_GROUP:
case TagConstants.CLASS_LOADER:
case TagConstants.CLASS_OBJECT:
return context.getIds().fromId((int) input.readLong());
default:
throw new RuntimeException("Should not reach here!");
}
}

private static Object readValue(PacketStream input, JDWPContext context) {
byte valueKind = input.readByte();
private static Object readValue(byte valueKind, PacketStream input, JDWPContext context) throws MissingReferenceException {
switch (valueKind) {
case TagConstants.VOID:
return Void.TYPE;
Expand All @@ -2962,14 +2964,20 @@ private static Object readValue(PacketStream input, JDWPContext context) {
return input.readLong();
case TagConstants.DOUBLE:
return input.readDouble();
case TagConstants.ARRAY:
case TagConstants.STRING:
case TagConstants.ARRAY:
case TagConstants.OBJECT:
case TagConstants.THREAD:
case TagConstants.THREAD_GROUP:
case TagConstants.CLASS_LOADER:
case TagConstants.CLASS_OBJECT:
return context.getIds().fromId((int) input.readLong());
Object value = context.getIds().fromId((int) input.readLong());
if (value == null) {
// the object was garbage collected, so callers need to reply with
// INVALID_OBJECT
throw new MissingReferenceException();
}
return value;
default:
throw new RuntimeException("Should not reach here!");
}
Expand Down Expand Up @@ -3297,4 +3305,8 @@ private static Object verifyClassObject(long classObjectId, PacketStream reply,
}
return object;
}

private static class MissingReferenceException extends Exception {
static final long serialVersionUID = -2187514293129322348L;
}
}