src/share/vm/classfile/verifier.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File bug_jdk8026065_1 Sdiff src/share/vm/classfile

src/share/vm/classfile/verifier.cpp

Print this page




2285       if (m->is_protected() && !mh->is_same_class_package(_klass())) {
2286         bool assignable = current_type().is_assignable_from(
2287           objectref_type, this, CHECK_VERIFY(this));
2288         if (!assignable) {
2289           verify_error(ErrorContext::bad_type(bci,
2290               TypeOrigin::cp(new_class_index, objectref_type),
2291               TypeOrigin::implicit(current_type())),
2292               "Bad access to protected <init> method");
2293           return;
2294         }
2295       }
2296     }
2297     current_frame->initialize_object(type, new_class_type);
2298   } else {
2299     verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx()),
2300         "Bad operand type when invoking <init>");
2301     return;
2302   }
2303 }
2304 


















2305 void ClassVerifier::verify_invoke_instructions(
2306     RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
2307     bool *this_uninit, VerificationType return_type,
2308     constantPoolHandle cp, TRAPS) {
2309   // Make sure the constant pool item is the right type
2310   u2 index = bcs->get_index_u2();
2311   Bytecodes::Code opcode = bcs->raw_code();
2312   unsigned int types;
2313   switch (opcode) {
2314     case Bytecodes::_invokeinterface:
2315       types = 1 << JVM_CONSTANT_InterfaceMethodref;
2316       break;
2317     case Bytecodes::_invokedynamic:
2318       types = 1 << JVM_CONSTANT_InvokeDynamic;
2319       break;
2320     case Bytecodes::_invokespecial:
2321     case Bytecodes::_invokestatic:
2322       types = (_klass->major_version() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
2323         (1 << JVM_CONSTANT_Methodref) :
2324         ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref));


2415   }
2416 
2417   if (opcode == Bytecodes::_invokedynamic) {
2418     address bcp = bcs->bcp();
2419     if (*(bcp+3) != 0 || *(bcp+4) != 0) {
2420       verify_error(ErrorContext::bad_code(bci),
2421           "Third and fourth operand bytes of invokedynamic must be zero");
2422       return;
2423     }
2424   }
2425 
2426   if (method_name->byte_at(0) == '<') {
2427     // Make sure <init> can only be invoked by invokespecial
2428     if (opcode != Bytecodes::_invokespecial ||
2429         method_name != vmSymbols::object_initializer_name()) {
2430       verify_error(ErrorContext::bad_code(bci),
2431           "Illegal call to internal method");
2432       return;
2433     }
2434   } else if (opcode == Bytecodes::_invokespecial
2435              && !ref_class_type.equals(current_type())
2436              && !ref_class_type.equals(VerificationType::reference_type(
2437                   current_class()->super()->name()))) {
2438     bool subtype = false;

2439     if (!current_class()->is_anonymous()) {
2440       subtype = ref_class_type.is_assignable_from(
2441                  current_type(), this, CHECK_VERIFY(this));
2442     } else {
2443       subtype = ref_class_type.is_assignable_from(VerificationType::reference_type(
2444                  current_class()->host_klass()->name()), this, CHECK_VERIFY(this));








2445     }
2446     if (!subtype) {
2447       verify_error(ErrorContext::bad_code(bci),
2448           "Bad invokespecial instruction: "
2449           "current class isn't assignable to reference class.");
2450        return;





2451     }

2452   }
2453   // Match method descriptor with operand stack
2454   for (int i = nargs - 1; i >= 0; i--) {  // Run backwards
2455     current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this));
2456   }
2457   // Check objectref on operand stack
2458   if (opcode != Bytecodes::_invokestatic &&
2459       opcode != Bytecodes::_invokedynamic) {
2460     if (method_name == vmSymbols::object_initializer_name()) {  // <init> method
2461       verify_invoke_init(bcs, index, ref_class_type, current_frame,
2462         code_length, this_uninit, cp, CHECK_VERIFY(this));
2463     } else {   // other methods
2464       // Ensures that target class is assignable to method class.
2465       if (opcode == Bytecodes::_invokespecial) {
2466         if (!current_class()->is_anonymous()) {
2467           current_frame->pop_stack(current_type(), CHECK_VERIFY(this));
2468         } else {
2469           // anonymous class invokespecial calls: check if the
2470           // objectref is a subtype of the host_klass of the current class
2471           // to allow an anonymous class to reference methods in the host_klass




2285       if (m->is_protected() && !mh->is_same_class_package(_klass())) {
2286         bool assignable = current_type().is_assignable_from(
2287           objectref_type, this, CHECK_VERIFY(this));
2288         if (!assignable) {
2289           verify_error(ErrorContext::bad_type(bci,
2290               TypeOrigin::cp(new_class_index, objectref_type),
2291               TypeOrigin::implicit(current_type())),
2292               "Bad access to protected <init> method");
2293           return;
2294         }
2295       }
2296     }
2297     current_frame->initialize_object(type, new_class_type);
2298   } else {
2299     verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx()),
2300         "Bad operand type when invoking <init>");
2301     return;
2302   }
2303 }
2304 
2305 bool ClassVerifier::is_same_or_direct_interface(
2306     instanceKlassHandle klass,
2307     VerificationType klass_type,
2308     VerificationType ref_class_type) {
2309   if (ref_class_type.equals(klass_type)) return true;
2310   Array<Klass*>* local_interfaces = klass->local_interfaces();
2311   if (local_interfaces != NULL) {
2312     for (int x = 0; x < local_interfaces->length(); x++) {
2313       Klass* k = local_interfaces->at(x);
2314       assert (k != NULL && k->is_interface(), "invalid interface");
2315       if (ref_class_type.equals(VerificationType::reference_type(k->name()))) {
2316         return true;
2317       }
2318     }
2319   }
2320   return false;
2321 }
2322 
2323 void ClassVerifier::verify_invoke_instructions(
2324     RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
2325     bool *this_uninit, VerificationType return_type,
2326     constantPoolHandle cp, TRAPS) {
2327   // Make sure the constant pool item is the right type
2328   u2 index = bcs->get_index_u2();
2329   Bytecodes::Code opcode = bcs->raw_code();
2330   unsigned int types;
2331   switch (opcode) {
2332     case Bytecodes::_invokeinterface:
2333       types = 1 << JVM_CONSTANT_InterfaceMethodref;
2334       break;
2335     case Bytecodes::_invokedynamic:
2336       types = 1 << JVM_CONSTANT_InvokeDynamic;
2337       break;
2338     case Bytecodes::_invokespecial:
2339     case Bytecodes::_invokestatic:
2340       types = (_klass->major_version() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
2341         (1 << JVM_CONSTANT_Methodref) :
2342         ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref));


2433   }
2434 
2435   if (opcode == Bytecodes::_invokedynamic) {
2436     address bcp = bcs->bcp();
2437     if (*(bcp+3) != 0 || *(bcp+4) != 0) {
2438       verify_error(ErrorContext::bad_code(bci),
2439           "Third and fourth operand bytes of invokedynamic must be zero");
2440       return;
2441     }
2442   }
2443 
2444   if (method_name->byte_at(0) == '<') {
2445     // Make sure <init> can only be invoked by invokespecial
2446     if (opcode != Bytecodes::_invokespecial ||
2447         method_name != vmSymbols::object_initializer_name()) {
2448       verify_error(ErrorContext::bad_code(bci),
2449           "Illegal call to internal method");
2450       return;
2451     }
2452   } else if (opcode == Bytecodes::_invokespecial
2453              && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
2454              && !ref_class_type.equals(VerificationType::reference_type(
2455                   current_class()->super()->name()))) {
2456     bool subtype = false;
2457     bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
2458     if (!current_class()->is_anonymous()) {
2459       subtype = ref_class_type.is_assignable_from(
2460                  current_type(), this, CHECK_VERIFY(this));
2461     } else {
2462       VerificationType host_klass_type =
2463                         VerificationType::reference_type(current_class()->host_klass()->name());
2464       subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this));
2465 
2466       // If invokespecial of IMR, need to recheck for same or 
2467       // direct interface relative to the host class
2468       have_imr_indirect = (have_imr_indirect && 
2469                            !is_same_or_direct_interface(
2470                              InstanceKlass::cast(current_class()->host_klass()),
2471                              host_klass_type, ref_class_type));
2472     }
2473     if (!subtype) {
2474       verify_error(ErrorContext::bad_code(bci),
2475           "Bad invokespecial instruction: "
2476           "current class isn't assignable to reference class.");
2477        return;
2478     } else if (have_imr_indirect) {
2479       verify_error(ErrorContext::bad_code(bci),
2480           "Bad invokespecial instruction: "
2481           "interface method reference is in an indirect superinterface.");
2482       return;
2483     }
2484 
2485   }
2486   // Match method descriptor with operand stack
2487   for (int i = nargs - 1; i >= 0; i--) {  // Run backwards
2488     current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this));
2489   }
2490   // Check objectref on operand stack
2491   if (opcode != Bytecodes::_invokestatic &&
2492       opcode != Bytecodes::_invokedynamic) {
2493     if (method_name == vmSymbols::object_initializer_name()) {  // <init> method
2494       verify_invoke_init(bcs, index, ref_class_type, current_frame,
2495         code_length, this_uninit, cp, CHECK_VERIFY(this));
2496     } else {   // other methods
2497       // Ensures that target class is assignable to method class.
2498       if (opcode == Bytecodes::_invokespecial) {
2499         if (!current_class()->is_anonymous()) {
2500           current_frame->pop_stack(current_type(), CHECK_VERIFY(this));
2501         } else {
2502           // anonymous class invokespecial calls: check if the
2503           // objectref is a subtype of the host_klass of the current class
2504           // to allow an anonymous class to reference methods in the host_klass


src/share/vm/classfile/verifier.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File