8036533: Method for correct defaults
8036156: Limit default method hierarchy
Summary: Fix protected access checks
Reviewed-by: coleenp, lfoltan, acorn, ahgross
--- a/hotspot/src/share/vm/classfile/stackMapFrame.cpp Tue Oct 14 13:10:50 2014 -0700
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.cpp Tue Jul 22 16:16:51 2014 +0400
@@ -148,7 +148,7 @@
VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
int32_t i = 0;
for (i = 0; i < len; i++) {
- if (!to[i].is_assignable_from(from[i], verifier(), THREAD)) {
+ if (!to[i].is_assignable_from(from[i], verifier(), false, THREAD)) {
break;
}
}
@@ -245,7 +245,7 @@
}
VerificationType top = _stack[--_stack_size];
bool subtype = type.is_assignable_from(
- top, verifier(), CHECK_(VerificationType::bogus_type()));
+ top, verifier(), false, CHECK_(VerificationType::bogus_type()));
if (!subtype) {
verifier()->verify_error(
ErrorContext::bad_type(_offset, stack_top_ctx(),
@@ -265,7 +265,7 @@
return VerificationType::bogus_type();
}
bool subtype = type.is_assignable_from(_locals[index],
- verifier(), CHECK_(VerificationType::bogus_type()));
+ verifier(), false, CHECK_(VerificationType::bogus_type()));
if (!subtype) {
verifier()->verify_error(
ErrorContext::bad_type(_offset,
@@ -288,14 +288,14 @@
"get long/double overflows locals");
return;
}
- bool subtype = type1.is_assignable_from(_locals[index], verifier(), CHECK);
+ bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK);
if (!subtype) {
verifier()->verify_error(
ErrorContext::bad_type(_offset,
TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
"Bad local variable type");
} else {
- subtype = type2.is_assignable_from(_locals[index + 1], verifier(), CHECK);
+ subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK);
if (!subtype) {
/* Unreachable? All local store routines convert a split long or double
* into a TOP during the store. So we should never end up seeing an
--- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp Tue Oct 14 13:10:50 2014 -0700
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp Tue Jul 22 16:16:51 2014 +0400
@@ -234,7 +234,7 @@
if (_stack_size != 0) {
VerificationType top = _stack[_stack_size - 1];
bool subtype = type.is_assignable_from(
- top, verifier(), CHECK_(VerificationType::bogus_type()));
+ top, verifier(), false, CHECK_(VerificationType::bogus_type()));
if (subtype) {
--_stack_size;
return top;
@@ -249,9 +249,9 @@
assert(type2.is_long() || type2.is_double(), "must be long/double_2");
if (_stack_size >= 2) {
VerificationType top1 = _stack[_stack_size - 1];
- bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK);
+ bool subtype1 = type1.is_assignable_from(top1, verifier(), false, CHECK);
VerificationType top2 = _stack[_stack_size - 2];
- bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK);
+ bool subtype2 = type2.is_assignable_from(top2, verifier(), false, CHECK);
if (subtype1 && subtype2) {
_stack_size -= 2;
return;
--- a/hotspot/src/share/vm/classfile/verificationType.cpp Tue Oct 14 13:10:50 2014 -0700
+++ b/hotspot/src/share/vm/classfile/verificationType.cpp Tue Jul 22 16:16:51 2014 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,8 @@
}
bool VerificationType::is_reference_assignable_from(
- const VerificationType& from, ClassVerifier* context, TRAPS) const {
+ const VerificationType& from, ClassVerifier* context,
+ bool from_field_is_protected, TRAPS) const {
instanceKlassHandle klass = context->current_class();
if (from.is_null()) {
// null is assignable to any reference
@@ -62,9 +63,11 @@
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
KlassHandle this_class(THREAD, obj);
- if (this_class->is_interface()) {
- // We treat interfaces as java.lang.Object, including
- // java.lang.Cloneable and java.io.Serializable
+ if (this_class->is_interface() && (!from_field_is_protected ||
+ from.name() != vmSymbols::java_lang_Object())) {
+ // If we are not trying to access a protected field or method in
+ // java.lang.Object then we treat interfaces as java.lang.Object,
+ // including java.lang.Cloneable and java.io.Serializable.
return true;
} else if (from.is_object()) {
Klass* from_class = SystemDictionary::resolve_or_fail(
@@ -76,7 +79,8 @@
VerificationType comp_this = get_component(context, CHECK_false);
VerificationType comp_from = from.get_component(context, CHECK_false);
if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
- return comp_this.is_assignable_from(comp_from, context, CHECK_false);
+ return comp_this.is_assignable_from(comp_from, context,
+ from_field_is_protected, CHECK_false);
}
}
return false;
--- a/hotspot/src/share/vm/classfile/verificationType.hpp Tue Oct 14 13:10:50 2014 -0700
+++ b/hotspot/src/share/vm/classfile/verificationType.hpp Tue Jul 22 16:16:51 2014 +0400
@@ -265,7 +265,8 @@
// is assignable to another. Returns true if one can assign 'from' to
// this.
bool is_assignable_from(
- const VerificationType& from, ClassVerifier* context, TRAPS) const {
+ const VerificationType& from, ClassVerifier* context,
+ bool from_field_is_protected, TRAPS) const {
if (equals(from) || is_bogus()) {
return true;
} else {
@@ -286,7 +287,9 @@
return from.is_integer();
default:
if (is_reference() && from.is_reference()) {
- return is_reference_assignable_from(from, context, CHECK_false);
+ return is_reference_assignable_from(from, context,
+ from_field_is_protected,
+ CHECK_false);
} else {
return false;
}
@@ -308,7 +311,8 @@
private:
bool is_reference_assignable_from(
- const VerificationType&, ClassVerifier*, TRAPS) const;
+ const VerificationType&, ClassVerifier*, bool from_field_is_protected,
+ TRAPS) const;
};
#endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP
--- a/hotspot/src/share/vm/classfile/verifier.cpp Tue Oct 14 13:10:50 2014 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Tue Jul 22 16:16:51 2014 +0400
@@ -1721,7 +1721,7 @@
VerificationType throwable =
VerificationType::reference_type(vmSymbols::java_lang_Throwable());
bool is_subclass = throwable.is_assignable_from(
- catch_type, this, CHECK_VERIFY(this));
+ catch_type, this, false, CHECK_VERIFY(this));
if (!is_subclass) {
// 4286534: should throw VerifyError according to recent spec change
verify_error(ErrorContext::bad_type(handler_pc,
@@ -2174,7 +2174,7 @@
stack_object_type = current_type();
}
is_assignable = target_class_type.is_assignable_from(
- stack_object_type, this, CHECK_VERIFY(this));
+ stack_object_type, this, false, CHECK_VERIFY(this));
if (!is_assignable) {
verify_error(ErrorContext::bad_type(bci,
current_frame->stack_top_ctx(),
@@ -2201,7 +2201,7 @@
// It's protected access, check if stack object is assignable to
// current class.
is_assignable = current_type().is_assignable_from(
- stack_object_type, this, CHECK_VERIFY(this));
+ stack_object_type, this, true, CHECK_VERIFY(this));
if (!is_assignable) {
verify_error(ErrorContext::bad_type(bci,
current_frame->stack_top_ctx(),
@@ -2475,7 +2475,7 @@
instanceKlassHandle mh(THREAD, m->method_holder());
if (m->is_protected() && !mh->is_same_class_package(_klass())) {
bool assignable = current_type().is_assignable_from(
- objectref_type, this, CHECK_VERIFY(this));
+ objectref_type, this, true, CHECK_VERIFY(this));
if (!assignable) {
verify_error(ErrorContext::bad_type(bci,
TypeOrigin::cp(new_class_index, objectref_type),
@@ -2646,11 +2646,11 @@
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));
+ current_type(), this, false, 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));
+ subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this));
// If invokespecial of IMR, need to recheck for same or
// direct interface relative to the host class
@@ -2694,7 +2694,7 @@
VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
VerificationType hosttype =
VerificationType::reference_type(current_class()->host_klass()->name());
- bool subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this));
+ bool subtype = hosttype.is_assignable_from(top, this, false, CHECK_VERIFY(this));
if (!subtype) {
verify_error( ErrorContext::bad_type(current_frame->offset(),
current_frame->stack_top_ctx(),
@@ -2719,7 +2719,7 @@
// It's protected access, check if stack object is
// assignable to current class.
bool is_assignable = current_type().is_assignable_from(
- stack_object_type, this, CHECK_VERIFY(this));
+ stack_object_type, this, true, CHECK_VERIFY(this));
if (!is_assignable) {
if (ref_class_type.name() == vmSymbols::java_lang_Object()
&& stack_object_type.is_array()
@@ -2902,7 +2902,7 @@
"Method expects a return value");
return;
}
- bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this));
+ bool match = return_type.is_assignable_from(type, this, false, CHECK_VERIFY(this));
if (!match) {
verify_error(ErrorContext::bad_type(bci,
current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
--- a/hotspot/src/share/vm/runtime/reflection.cpp Tue Oct 14 13:10:50 2014 -0700
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Tue Jul 22 16:16:51 2014 +0400
@@ -507,7 +507,8 @@
if (access.is_protected()) {
if (!protected_restriction) {
// See if current_class (or outermost host class) is a subclass of field_class
- if (host_class->is_subclass_of(field_class)) {
+ // An interface may not access protected members of j.l.Object
+ if (!host_class->is_interface() && host_class->is_subclass_of(field_class)) {
if (access.is_static() || // static fields are ok, see 6622385
current_class == resolved_class ||
field_class == resolved_class ||