1 /*
2 * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
47 ShouldNotReachHere();
48 return bogus_type();
49 }
50 }
51
52 bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
53 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
54 HandleMark hm(THREAD);
55 Klass* this_class;
56 if (klass->is_hidden() && klass->name() == name) {
57 this_class = klass;
58 } else {
59 this_class = SystemDictionary::resolve_or_fail(
60 name, Handle(THREAD, klass->class_loader()),
61 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
62 if (log_is_enabled(Debug, class, resolve)) {
63 Verifier::trace_class_resolution(this_class, klass);
64 }
65 }
66
67 if (this_class->is_interface() && (!from_field_is_protected ||
68 from_name != vmSymbols::java_lang_Object())) {
69 // If we are not trying to access a protected field or method in
70 // java.lang.Object then, for arrays, we only allow assignability
71 // to interfaces java.lang.Cloneable and java.io.Serializable.
72 // Otherwise, we treat interfaces as java.lang.Object.
73 return !from_is_array ||
74 this_class == vmClasses::Cloneable_klass() ||
75 this_class == vmClasses::Serializable_klass();
76 } else if (from_is_object) {
77 Klass* from_class;
78 if (klass->is_hidden() && klass->name() == from_name) {
79 from_class = klass;
80 } else {
81 from_class = SystemDictionary::resolve_or_fail(
82 from_name, Handle(THREAD, klass->class_loader()),
83 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
84 if (log_is_enabled(Debug, class, resolve)) {
85 Verifier::trace_class_resolution(from_class, klass);
86 }
87 }
88 return from_class->is_subclass_of(this_class);
89 }
90
91 return false;
107 if (name() == vmSymbols::java_lang_Object()) {
108 // any object or array is assignable to java.lang.Object
109 return true;
110 }
111
112 if (CDSConfig::is_dumping_archive()) {
113 if (SystemDictionaryShared::add_verification_constraint(klass,
114 name(), from.name(), from_field_is_protected, from.is_array(),
115 from.is_object())) {
116 // If add_verification_constraint() returns true, the resolution/check should be
117 // delayed until runtime.
118 return true;
119 }
120 }
121
122 return resolve_and_check_assignability(klass, name(), from.name(),
123 from_field_is_protected, from.is_array(), from.is_object(), THREAD);
124 } else if (is_array() && from.is_array()) {
125 VerificationType comp_this = get_component(context);
126 VerificationType comp_from = from.get_component(context);
127 if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
128 return comp_this.is_component_assignable_from(comp_from, context,
129 from_field_is_protected, THREAD);
130 }
131 }
132 return false;
133 }
134
135 VerificationType VerificationType::get_component(ClassVerifier *context) const {
136 assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
137 SignatureStream ss(name(), false);
138 ss.skip_array_prefix(1);
139 switch (ss.type()) {
140 case T_BOOLEAN: return VerificationType(Boolean);
141 case T_BYTE: return VerificationType(Byte);
142 case T_CHAR: return VerificationType(Char);
143 case T_SHORT: return VerificationType(Short);
144 case T_INT: return VerificationType(Integer);
145 case T_LONG: return VerificationType(Long);
146 case T_FLOAT: return VerificationType(Float);
|
1 /*
2 * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
47 ShouldNotReachHere();
48 return bogus_type();
49 }
50 }
51
52 bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
53 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
54 HandleMark hm(THREAD);
55 Klass* this_class;
56 if (klass->is_hidden() && klass->name() == name) {
57 this_class = klass;
58 } else {
59 this_class = SystemDictionary::resolve_or_fail(
60 name, Handle(THREAD, klass->class_loader()),
61 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
62 if (log_is_enabled(Debug, class, resolve)) {
63 Verifier::trace_class_resolution(this_class, klass);
64 }
65 }
66
67 // Need to do this check when called from CDS.
68 // if (this_class->access_flags().is_primitive_class()) {
69 // Klass* from_class = SystemDictionary::resolve_or_fail(
70 // from_name, Handle(THREAD, klass->class_loader()),
71 // Handle(THREAD, klass->protection_domain()), true, CHECK_false);
72 // return from_class == this_class;
73 // }
74 if (this_class->is_interface() && (!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 this_class == vmClasses::Cloneable_klass() ||
82 this_class == vmClasses::Serializable_klass();
83 } else if (from_is_object) {
84 Klass* from_class;
85 if (klass->is_hidden() && klass->name() == from_name) {
86 from_class = klass;
87 } else {
88 from_class = SystemDictionary::resolve_or_fail(
89 from_name, Handle(THREAD, klass->class_loader()),
90 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
91 if (log_is_enabled(Debug, class, resolve)) {
92 Verifier::trace_class_resolution(from_class, klass);
93 }
94 }
95 return from_class->is_subclass_of(this_class);
96 }
97
98 return false;
114 if (name() == vmSymbols::java_lang_Object()) {
115 // any object or array is assignable to java.lang.Object
116 return true;
117 }
118
119 if (CDSConfig::is_dumping_archive()) {
120 if (SystemDictionaryShared::add_verification_constraint(klass,
121 name(), from.name(), from_field_is_protected, from.is_array(),
122 from.is_object())) {
123 // If add_verification_constraint() returns true, the resolution/check should be
124 // delayed until runtime.
125 return true;
126 }
127 }
128
129 return resolve_and_check_assignability(klass, name(), from.name(),
130 from_field_is_protected, from.is_array(), from.is_object(), THREAD);
131 } else if (is_array() && from.is_array()) {
132 VerificationType comp_this = get_component(context);
133 VerificationType comp_from = from.get_component(context);
134
135 if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
136 return comp_this.is_component_assignable_from(comp_from, context,
137 from_field_is_protected, THREAD);
138 }
139 }
140 return false;
141 }
142
143 VerificationType VerificationType::get_component(ClassVerifier *context) const {
144 assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
145 SignatureStream ss(name(), false);
146 ss.skip_array_prefix(1);
147 switch (ss.type()) {
148 case T_BOOLEAN: return VerificationType(Boolean);
149 case T_BYTE: return VerificationType(Byte);
150 case T_CHAR: return VerificationType(Char);
151 case T_SHORT: return VerificationType(Short);
152 case T_INT: return VerificationType(Integer);
153 case T_LONG: return VerificationType(Long);
154 case T_FLOAT: return VerificationType(Float);
|