mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8247444: Trust final fields in records
Co-authored-by: Christoph Dreis <christoph.dreis@freenet.de> Reviewed-by: jrose, dholmes, forax, coleenp, vlivanov
This commit is contained in:
parent
983e012c9f
commit
f2b191a6e9
26 changed files with 227 additions and 49 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2020, 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
|
||||
|
@ -480,7 +480,8 @@ final class MemberName implements Member, Cloneable {
|
|||
IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
|
||||
IS_FIELD = MN_IS_FIELD, // field
|
||||
IS_TYPE = MN_IS_TYPE, // nested type
|
||||
CALLER_SENSITIVE = MN_CALLER_SENSITIVE; // @CallerSensitive annotation detected
|
||||
CALLER_SENSITIVE = MN_CALLER_SENSITIVE, // @CallerSensitive annotation detected
|
||||
TRUSTED_FINAL = MN_TRUSTED_FINAL; // trusted final field
|
||||
|
||||
static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
|
||||
static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
|
||||
|
@ -520,6 +521,8 @@ final class MemberName implements Member, Cloneable {
|
|||
public boolean isCallerSensitive() {
|
||||
return testAllFlags(CALLER_SENSITIVE);
|
||||
}
|
||||
/** Query whether this member is a trusted final field. */
|
||||
public boolean isTrustedFinalField() { return testAllFlags(TRUSTED_FINAL|IS_FIELD); }
|
||||
|
||||
/** Utility method to query whether this member is accessible from a given lookup class. */
|
||||
public boolean isAccessibleFrom(Class<?> lookupClass) {
|
||||
|
|
|
@ -118,6 +118,7 @@ class MethodHandleNatives {
|
|||
MN_IS_FIELD = 0x00040000, // field
|
||||
MN_IS_TYPE = 0x00080000, // nested type
|
||||
MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
|
||||
MN_TRUSTED_FINAL = 0x00200000, // trusted final field
|
||||
MN_REFERENCE_KIND_SHIFT = 24, // refKind
|
||||
MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
|
||||
// The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
|
||||
|
|
|
@ -3273,10 +3273,10 @@ return mh1;
|
|||
private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
|
||||
MemberName field = new MemberName(f, isSetter);
|
||||
if (isSetter && field.isFinal()) {
|
||||
if (field.isStatic()) {
|
||||
throw field.makeAccessException("static final field has no write access", this);
|
||||
} else if (field.getDeclaringClass().isHidden()){
|
||||
throw field.makeAccessException("final field in a hidden class has no write access", this);
|
||||
if (field.isTrustedFinalField()) {
|
||||
String msg = field.isStatic() ? "static final field has no write access"
|
||||
: "final field has no write access";
|
||||
throw field.makeAccessException(msg, this);
|
||||
}
|
||||
}
|
||||
assert(isSetter
|
||||
|
@ -3839,7 +3839,7 @@ return mh1;
|
|||
refc = lookupClass();
|
||||
}
|
||||
return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(),
|
||||
this.allowedModes == TRUSTED && !getField.getDeclaringClass().isHidden());
|
||||
this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
|
||||
}
|
||||
/** Check access and get the requested constructor. */
|
||||
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue