< prev index next >

src/hotspot/share/classfile/verificationType.cpp

Print this page

 49 }
 50 
 51 // Potentially resolve the target class and from class, and check whether the from class is assignable
 52 // to the target class. The current_klass is the class being verified - it could also be the target in some
 53 // cases, and otherwise is needed to obtain the correct classloader for resolving the other classes.
 54 bool VerificationType::resolve_and_check_assignability(InstanceKlass* current_klass, Symbol* target_name, Symbol* from_name,
 55                                                        bool from_field_is_protected, bool from_is_array,
 56                                                        bool from_is_object, bool* target_is_interface, TRAPS) {
 57   HandleMark hm(THREAD);
 58   Klass* target_klass;
 59   if (current_klass->is_hidden() && current_klass->name() == target_name) {
 60     target_klass = current_klass;
 61   } else {
 62     target_klass = SystemDictionary::resolve_or_fail(
 63       target_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false);
 64     if (log_is_enabled(Debug, class, resolve)) {
 65       Verifier::trace_class_resolution(target_klass, current_klass);
 66     }
 67   }
 68 







 69   bool is_intf = target_klass->is_interface();
 70   if (target_is_interface != nullptr) {
 71     *target_is_interface = is_intf;
 72   }
 73 
 74   if (is_intf && (!from_field_is_protected ||
 75       from_name != vmSymbols::java_lang_Object())) {
 76     // If we are not trying to access a protected field or method in
 77     // java.lang.Object then, for arrays, we only allow assignability
 78     // to interfaces java.lang.Cloneable and java.io.Serializable.
 79     // Otherwise, we treat interfaces as java.lang.Object.
 80     return !from_is_array ||
 81       target_klass == vmClasses::Cloneable_klass() ||
 82       target_klass == vmClasses::Serializable_klass();
 83   } else if (from_is_object) {
 84     Klass* from_klass;
 85     if (current_klass->is_hidden() && current_klass->name() == from_name) {
 86       from_klass = current_klass;
 87     } else {
 88       from_klass = SystemDictionary::resolve_or_fail(
 89         from_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false);
 90       if (log_is_enabled(Debug, class, resolve)) {
 91         Verifier::trace_class_resolution(from_klass, current_klass);
 92       }
 93     }
 94     return from_klass->is_subclass_of(target_klass);
 95   }
 96 
 97   return false;
 98 }

117 
118 #if INCLUDE_CDS
119     if (CDSConfig::is_dumping_archive()) {
120       bool skip_assignability_check = false;
121       SystemDictionaryShared::add_verification_constraint(context->current_class(),
122               name(), from.name(), from_field_is_protected, from.is_array(),
123               from.is_object(), &skip_assignability_check);
124       if (skip_assignability_check) {
125         // We are not able to resolve name() or from.name(). The actual assignability check
126         // will be delayed until runtime.
127         return true;
128       }
129     }
130 #endif
131     return resolve_and_check_assignability(context->current_class(), name(), from.name(),
132                                            from_field_is_protected, from.is_array(),
133                                            from.is_object(), this_is_interface, THREAD);
134   } else if (is_array() && from.is_array()) {
135     VerificationType comp_this = get_component(context);
136     VerificationType comp_from = from.get_component(context);

137     if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
138       return comp_this.is_component_assignable_from(comp_from, context,
139                                                     from_field_is_protected, THREAD);
140     }
141   }
142   return false;
143 }
144 
145 VerificationType VerificationType::get_component(ClassVerifier *context) const {
146   assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
147   SignatureStream ss(name(), false);
148   ss.skip_array_prefix(1);
149   switch (ss.type()) {
150     case T_BOOLEAN: return VerificationType(Boolean);
151     case T_BYTE:    return VerificationType(Byte);
152     case T_CHAR:    return VerificationType(Char);
153     case T_SHORT:   return VerificationType(Short);
154     case T_INT:     return VerificationType(Integer);
155     case T_LONG:    return VerificationType(Long);
156     case T_FLOAT:   return VerificationType(Float);

 49 }
 50 
 51 // Potentially resolve the target class and from class, and check whether the from class is assignable
 52 // to the target class. The current_klass is the class being verified - it could also be the target in some
 53 // cases, and otherwise is needed to obtain the correct classloader for resolving the other classes.
 54 bool VerificationType::resolve_and_check_assignability(InstanceKlass* current_klass, Symbol* target_name, Symbol* from_name,
 55                                                        bool from_field_is_protected, bool from_is_array,
 56                                                        bool from_is_object, bool* target_is_interface, TRAPS) {
 57   HandleMark hm(THREAD);
 58   Klass* target_klass;
 59   if (current_klass->is_hidden() && current_klass->name() == target_name) {
 60     target_klass = current_klass;
 61   } else {
 62     target_klass = SystemDictionary::resolve_or_fail(
 63       target_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false);
 64     if (log_is_enabled(Debug, class, resolve)) {
 65       Verifier::trace_class_resolution(target_klass, current_klass);
 66     }
 67   }
 68 
 69   // Need to do this check when called from CDS.
 70   // if (this_class->access_flags().is_primitive_class()) {
 71   //   Klass* from_class = SystemDictionary::resolve_or_fail(
 72   //     from_name, Handle(THREAD, klass->class_loader()),
 73   //     Handle(THREAD, klass->protection_domain()), true, CHECK_false);
 74   //   return from_class == this_class;
 75   // }
 76   bool is_intf = target_klass->is_interface();
 77   if (target_is_interface != nullptr) {
 78     *target_is_interface = is_intf;
 79   }
 80 
 81   if (is_intf && (!from_field_is_protected ||
 82       from_name != vmSymbols::java_lang_Object())) {
 83     // If we are not trying to access a protected field or method in
 84     // java.lang.Object then, for arrays, we only allow assignability
 85     // to interfaces java.lang.Cloneable and java.io.Serializable
 86     // Otherwise, we treat interfaces as java.lang.Object.
 87     return !from_is_array ||
 88       target_klass == vmClasses::Cloneable_klass() ||
 89       target_klass == vmClasses::Serializable_klass();
 90   } else if (from_is_object) {
 91     Klass* from_klass;
 92     if (current_klass->is_hidden() && current_klass->name() == from_name) {
 93       from_klass = current_klass;
 94     } else {
 95       from_klass = SystemDictionary::resolve_or_fail(
 96         from_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false);
 97       if (log_is_enabled(Debug, class, resolve)) {
 98         Verifier::trace_class_resolution(from_klass, current_klass);
 99       }
100     }
101     return from_klass->is_subclass_of(target_klass);
102   }
103 
104   return false;
105 }

124 
125 #if INCLUDE_CDS
126     if (CDSConfig::is_dumping_archive()) {
127       bool skip_assignability_check = false;
128       SystemDictionaryShared::add_verification_constraint(context->current_class(),
129               name(), from.name(), from_field_is_protected, from.is_array(),
130               from.is_object(), &skip_assignability_check);
131       if (skip_assignability_check) {
132         // We are not able to resolve name() or from.name(). The actual assignability check
133         // will be delayed until runtime.
134         return true;
135       }
136     }
137 #endif
138     return resolve_and_check_assignability(context->current_class(), name(), from.name(),
139                                            from_field_is_protected, from.is_array(),
140                                            from.is_object(), this_is_interface, THREAD);
141   } else if (is_array() && from.is_array()) {
142     VerificationType comp_this = get_component(context);
143     VerificationType comp_from = from.get_component(context);
144 
145     if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
146       return comp_this.is_component_assignable_from(comp_from, context,
147                                                     from_field_is_protected, THREAD);
148     }
149   }
150   return false;
151 }
152 
153 VerificationType VerificationType::get_component(ClassVerifier *context) const {
154   assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
155   SignatureStream ss(name(), false);
156   ss.skip_array_prefix(1);
157   switch (ss.type()) {
158     case T_BOOLEAN: return VerificationType(Boolean);
159     case T_BYTE:    return VerificationType(Byte);
160     case T_CHAR:    return VerificationType(Char);
161     case T_SHORT:   return VerificationType(Short);
162     case T_INT:     return VerificationType(Integer);
163     case T_LONG:    return VerificationType(Long);
164     case T_FLOAT:   return VerificationType(Float);
< prev index next >