src/share/vm/classfile/verifier.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File bug_jdk8026065 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,2487 ---- 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 same_or_direct = false; 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)); ! // Recheck for same or direct interface relevant to the host class ! same_or_direct = 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 (!same_or_direct && + cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref) { + 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