8159515: Improve indy validation

Reviewed-by: jrose, hseigel, vlivanov, bmoloden, ctornqvi, mschoene
This commit is contained in:
Coleen Phillimore 2016-06-29 11:51:59 -04:00
parent b9b8be2d7c
commit 3be6827c7c

View File

@ -1293,14 +1293,13 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
case JVM_OPC_invokevirtual: case JVM_OPC_invokevirtual:
case JVM_OPC_invokespecial: case JVM_OPC_invokespecial:
case JVM_OPC_invokestatic: case JVM_OPC_invokestatic:
case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: { case JVM_OPC_invokeinterface: {
/* Make sure the constant pool item is the right type. */ /* Make sure the constant pool item is the right type. */
int key = (code[offset + 1] << 8) + code[offset + 2]; int key = (code[offset + 1] << 8) + code[offset + 2];
const char *methodname; const char *methodname;
jclass cb = context->class; jclass cb = context->class;
fullinfo_type clazz_info; fullinfo_type clazz_info;
int is_constructor, is_internal, is_invokedynamic; int is_constructor, is_internal;
int kind; int kind;
switch (opcode ) { switch (opcode ) {
@ -1309,9 +1308,6 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
? (1 << JVM_CONSTANT_Methodref) ? (1 << JVM_CONSTANT_Methodref)
: ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref))); : ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)));
break; break;
case JVM_OPC_invokedynamic:
kind = 1 << JVM_CONSTANT_NameAndType;
break;
case JVM_OPC_invokeinterface: case JVM_OPC_invokeinterface:
kind = 1 << JVM_CONSTANT_InterfaceMethodref; kind = 1 << JVM_CONSTANT_InterfaceMethodref;
break; break;
@ -1319,7 +1315,6 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
kind = 1 << JVM_CONSTANT_Methodref; kind = 1 << JVM_CONSTANT_Methodref;
} }
is_invokedynamic = opcode == JVM_OPC_invokedynamic;
/* Make sure the constant pool item is the right type. */ /* Make sure the constant pool item is the right type. */
verify_constant_pool_type(context, key, kind); verify_constant_pool_type(context, key, kind);
methodname = JVM_GetCPMethodNameUTF(env, cb, key); methodname = JVM_GetCPMethodNameUTF(env, cb, key);
@ -1328,9 +1323,6 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
is_internal = methodname[0] == '<'; is_internal = methodname[0] == '<';
pop_and_free(context); pop_and_free(context);
if (is_invokedynamic)
clazz_info = context->object_info; // anything will do
else
clazz_info = cp_index_to_class_fullinfo(context, key, clazz_info = cp_index_to_class_fullinfo(context, key,
JVM_CONSTANT_Methodref); JVM_CONSTANT_Methodref);
this_idata->operand.i = key; this_idata->operand.i = key;
@ -1387,17 +1379,15 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
"Fourth operand byte of invokeinterface must be zero"); "Fourth operand byte of invokeinterface must be zero");
} }
pop_and_free(context); pop_and_free(context);
} else if (opcode == JVM_OPC_invokedynamic) {
if (code[offset + 3] != 0 || code[offset + 4] != 0) {
CCerror(context,
"Third and fourth operand bytes of invokedynamic must be zero");
}
} else if (opcode == JVM_OPC_invokevirtual } else if (opcode == JVM_OPC_invokevirtual
|| opcode == JVM_OPC_invokespecial) || opcode == JVM_OPC_invokespecial)
set_protected(context, inumber, key, opcode); set_protected(context, inumber, key, opcode);
break; break;
} }
case JVM_OPC_invokedynamic:
CCerror(context,
"invokedynamic bytecode is not supported in this class file version");
case JVM_OPC_instanceof: case JVM_OPC_instanceof:
case JVM_OPC_checkcast: case JVM_OPC_checkcast:
@ -2085,7 +2075,6 @@ pop_stack(context_type *context, unsigned int inumber, stack_info_type *new_stac
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial: case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit: /* invokespecial call to <init> */ case JVM_OPC_invokeinit: /* invokespecial call to <init> */
case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: { case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* The top stuff on the stack depends on the method signature */ /* The top stuff on the stack depends on the method signature */
int operand = this_idata->operand.i; int operand = this_idata->operand.i;
@ -2101,8 +2090,7 @@ pop_stack(context_type *context, unsigned int inumber, stack_info_type *new_stac
print_formatted_methodname(context, operand); print_formatted_methodname(context, operand);
} }
#endif #endif
if (opcode != JVM_OPC_invokestatic && if (opcode != JVM_OPC_invokestatic)
opcode != JVM_OPC_invokedynamic)
/* First, push the object */ /* First, push the object */
*ip++ = (opcode == JVM_OPC_invokeinit ? '@' : 'A'); *ip++ = (opcode == JVM_OPC_invokeinit ? '@' : 'A');
for (p = signature + 1; *p != JVM_SIGNATURE_ENDFUNC; ) { for (p = signature + 1; *p != JVM_SIGNATURE_ENDFUNC; ) {
@ -2388,7 +2376,6 @@ pop_stack(context_type *context, unsigned int inumber, stack_info_type *new_stac
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial: case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit: case JVM_OPC_invokeinit:
case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: case JVM_OPC_invokestatic: { case JVM_OPC_invokeinterface: case JVM_OPC_invokestatic: {
int operand = this_idata->operand.i; int operand = this_idata->operand.i;
const char *signature = const char *signature =
@ -2398,8 +2385,7 @@ pop_stack(context_type *context, unsigned int inumber, stack_info_type *new_stac
int item; int item;
const char *p; const char *p;
check_and_push(context, signature, VM_STRING_UTF); check_and_push(context, signature, VM_STRING_UTF);
if (opcode == JVM_OPC_invokestatic || if (opcode == JVM_OPC_invokestatic) {
opcode == JVM_OPC_invokedynamic) {
item = 0; item = 0;
} else if (opcode == JVM_OPC_invokeinit) { } else if (opcode == JVM_OPC_invokeinit) {
fullinfo_type init_type = this_idata->operand2.fi; fullinfo_type init_type = this_idata->operand2.fi;
@ -2795,7 +2781,6 @@ push_stack(context_type *context, unsigned int inumber, stack_info_type *new_sta
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial: case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit: case JVM_OPC_invokeinit:
case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: { case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* Look to signature to determine correct result. */ /* Look to signature to determine correct result. */
int operand = this_idata->operand.i; int operand = this_idata->operand.i;