8299505: findVirtual on array classes incorrectly restricts the receiver type

Reviewed-by: mchung
This commit is contained in:
Chen Liang 2023-05-31 16:28:26 +00:00 committed by Mandy Chung
parent 42ca6e6942
commit 78aa5f3fc1
3 changed files with 95 additions and 16 deletions

View file

@ -3928,6 +3928,14 @@ return mh1;
throw m.makeAccessException(message, this);
}
private boolean isArrayClone(byte refKind, Class<?> refc, MemberName m) {
return Modifier.isProtected(m.getModifiers()) &&
refKind == REF_invokeVirtual &&
m.getDeclaringClass() == Object.class &&
m.getName().equals("clone") &&
refc.isArray();
}
/** Check public/protected/private bits on the symbolic reference class and its member. */
void checkAccess(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
assert(m.referenceKindIsConsistentWith(refKind) &&
@ -3936,11 +3944,7 @@ return mh1;
int allowedModes = this.allowedModes;
if (allowedModes == TRUSTED) return;
int mods = m.getModifiers();
if (Modifier.isProtected(mods) &&
refKind == REF_invokeVirtual &&
m.getDeclaringClass() == Object.class &&
m.getName().equals("clone") &&
refc.isArray()) {
if (isArrayClone(refKind, refc, m)) {
// The JVM does this hack also.
// (See ClassVerifier::verify_invoke_instructions
// and LinkResolver::check_method_accessability.)
@ -4100,7 +4104,12 @@ return mh1;
MethodHandle mh = dmh;
// Optionally narrow the receiver argument to lookupClass using restrictReceiver.
if ((doRestrict && refKind == REF_invokeSpecial) ||
(MethodHandleNatives.refKindHasReceiver(refKind) && restrictProtectedReceiver(method))) {
(MethodHandleNatives.refKindHasReceiver(refKind) &&
restrictProtectedReceiver(method) &&
// All arrays simply inherit the protected Object.clone method.
// The leading argument is already restricted to the requested
// array type (not the lookup class).
!isArrayClone(refKind, refc, method))) {
mh = restrictReceiver(method, dmh, lookupClass());
}
mh = maybeBindCaller(method, mh, boundCaller);