src/share/vm/classfile/verifier.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
bug_jdk8026065_1 Cdiff src/share/vm/classfile/verifier.cpp
src/share/vm/classfile/verifier.cpp
Print this page
*** 2300,2309 ****
--- 2300,2327 ----
"Bad operand type when invoking <init>");
return;
}
}
+ bool ClassVerifier::is_same_or_direct_interface(
+ instanceKlassHandle klass,
+ VerificationType klass_type,
+ VerificationType ref_class_type) {
+ if (ref_class_type.equals(klass_type)) return true;
+ Array<Klass*>* local_interfaces = klass->local_interfaces();
+ if (local_interfaces != NULL) {
+ for (int x = 0; x < local_interfaces->length(); x++) {
+ Klass* k = local_interfaces->at(x);
+ assert (k != NULL && k->is_interface(), "invalid interface");
+ if (ref_class_type.equals(VerificationType::reference_type(k->name()))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
void ClassVerifier::verify_invoke_instructions(
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
bool *this_uninit, VerificationType return_type,
constantPoolHandle cp, TRAPS) {
// Make sure the constant pool item is the right type
*** 2430,2456 ****
verify_error(ErrorContext::bad_code(bci),
"Illegal call to internal method");
return;
}
} else if (opcode == Bytecodes::_invokespecial
! && !ref_class_type.equals(current_type())
&& !ref_class_type.equals(VerificationType::reference_type(
current_class()->super()->name()))) {
bool subtype = false;
if (!current_class()->is_anonymous()) {
subtype = ref_class_type.is_assignable_from(
current_type(), this, CHECK_VERIFY(this));
} else {
! subtype = ref_class_type.is_assignable_from(VerificationType::reference_type(
! current_class()->host_klass()->name()), this, CHECK_VERIFY(this));
}
if (!subtype) {
verify_error(ErrorContext::bad_code(bci),
"Bad invokespecial instruction: "
"current class isn't assignable to reference class.");
return;
}
}
// Match method descriptor with operand stack
for (int i = nargs - 1; i >= 0; i--) { // Run backwards
current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this));
}
--- 2448,2489 ----
verify_error(ErrorContext::bad_code(bci),
"Illegal call to internal method");
return;
}
} else if (opcode == Bytecodes::_invokespecial
! && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
&& !ref_class_type.equals(VerificationType::reference_type(
current_class()->super()->name()))) {
bool subtype = false;
+ bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
if (!current_class()->is_anonymous()) {
subtype = ref_class_type.is_assignable_from(
current_type(), this, CHECK_VERIFY(this));
} else {
! VerificationType host_klass_type =
! VerificationType::reference_type(current_class()->host_klass()->name());
! subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this));
!
! // If invokespecial of IMR, need to recheck for same or
! // direct interface relative to the host class
! have_imr_indirect = (have_imr_indirect &&
! !is_same_or_direct_interface(
! InstanceKlass::cast(current_class()->host_klass()),
! host_klass_type, ref_class_type));
}
if (!subtype) {
verify_error(ErrorContext::bad_code(bci),
"Bad invokespecial instruction: "
"current class isn't assignable to reference class.");
return;
+ } else if (have_imr_indirect) {
+ verify_error(ErrorContext::bad_code(bci),
+ "Bad invokespecial instruction: "
+ "interface method reference is in an indirect superinterface.");
+ return;
}
+
}
// Match method descriptor with operand stack
for (int i = nargs - 1; i >= 0; i--) { // Run backwards
current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this));
}
src/share/vm/classfile/verifier.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File