< prev index next >

src/java.base/share/classes/sun/invoke/util/VerifyAccess.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2008, 2017, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2008, 2018, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 42,52 **** private static final int MODULE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.MODULE; private static final int PACKAGE_ONLY = 0; private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE; private static final int PROTECTED_OR_PACKAGE_ALLOWED = (PACKAGE_ALLOWED|PROTECTED); private static final int ALL_ACCESS_MODES = (PUBLIC|PRIVATE|PROTECTED|PACKAGE_ONLY); - private static final boolean ALLOW_NESTMATE_ACCESS = false; /** * Evaluate the JVM linkage rules for access to the given method * on behalf of a caller class which proposes to perform the access. * Return true if the caller class has privileges to invoke a method --- 42,51 ----
*** 60,86 **** * Also relevant is the class used to make the initial symbolic reference * to the member ({@code refc}). If this latter class is not distinguished, * the defining class should be passed for both arguments ({@code defc == refc}). * <h3>JVM Specification, 5.4.4 "Access Control"</h3> * A field or method R is accessible to a class or interface D if ! * and only if any of the following conditions is true:<ul> ! * <li>R is public. * <li>R is protected and is declared in a class C, and D is either ! * a subclass of C or C itself. Furthermore, if R is not ! * static, then the symbolic reference to R must contain a ! * symbolic reference to a class T, such that T is either a ! * subclass of D, a superclass of D or D itself. ! * <li>R is either protected or has default access (that is, ! * neither public nor protected nor private), and is declared ! * by a class in the same runtime package as D. ! * <li>R is private and is declared in D. * </ul> ! * This discussion of access control omits a related restriction ! * on the target of a protected field access or method invocation ! * (the target must be of class D or a subtype of D). That ! * requirement is checked as part of the verification process ! * (5.4.1); it is not part of link-time access control. * @param refc the class used in the symbolic reference to the proposed member * @param defc the class in which the proposed member is actually defined * @param mods modifier flags for the proposed member * @param lookupClass the class for which the access check is being made * @return true iff the accessing class can access such a member --- 59,91 ---- * Also relevant is the class used to make the initial symbolic reference * to the member ({@code refc}). If this latter class is not distinguished, * the defining class should be passed for both arguments ({@code defc == refc}). * <h3>JVM Specification, 5.4.4 "Access Control"</h3> * A field or method R is accessible to a class or interface D if ! * and only if any of the following is true: ! * <ul> ! * <li>R is public.</li> * <li>R is protected and is declared in a class C, and D is either ! * a subclass of C or C itself. Furthermore, if R is not static, ! * then the symbolic reference to R must contain a symbolic ! * reference to a class T, such that T is either a subclass of D, ! * a superclass of D, or D itself. ! * <p>During verification, it was also required that, even if T is ! * a superclass of D, the target reference of a protected instance ! * field access or method invocation must be an instance of D or a ! * subclass of D (4.10.1.8).</p></li> ! * <li>R is either protected or has default access (that is, neither ! * public nor protected nor private), and is declared by a class ! * in the same run-time package as D.</li> ! * <li>R is private and is declared in D by a class or interface ! * belonging to the same nest as D.</li> * </ul> ! * If a referenced field or method is not accessible, access checking ! * throws an IllegalAccessError. If an exception is thrown while ! * attempting to determine the nest host of a class or interface, ! * access checking fails for the same reason. ! * * @param refc the class used in the symbolic reference to the proposed member * @param defc the class in which the proposed member is actually defined * @param mods modifier flags for the proposed member * @param lookupClass the class for which the access check is being made * @return true iff the accessing class can access such a member
*** 98,108 **** return false; } // Usually refc and defc are the same, but verify defc also in case they differ. if (defc == lookupClass && (allowedModes & PRIVATE) != 0) ! return true; // easy check; all self-access is OK switch (mods & ALL_ACCESS_MODES) { case PUBLIC: return true; // already checked above case PROTECTED: assert !defc.isInterface(); // protected members aren't allowed in interfaces --- 103,114 ---- return false; } // Usually refc and defc are the same, but verify defc also in case they differ. if (defc == lookupClass && (allowedModes & PRIVATE) != 0) ! return true; // easy check; all self-access is OK with a private lookup ! switch (mods & ALL_ACCESS_MODES) { case PUBLIC: return true; // already checked above case PROTECTED: assert !defc.isInterface(); // protected members aren't allowed in interfaces
*** 124,141 **** case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. assert !defc.isInterface(); // package-private members aren't allowed in interfaces return ((allowedModes & PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)); case PRIVATE: ! // Loosened rules for privates follows access rules for inner classes. ! return (ALLOW_NESTMATE_ACCESS && ! (allowedModes & PRIVATE) != 0 && ! isSamePackageMember(defc, lookupClass)); default: throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods)); } } static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) { return (refc == lookupClass || isSubClass(refc, lookupClass) || isSubClass(lookupClass, refc)); --- 130,153 ---- case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. assert !defc.isInterface(); // package-private members aren't allowed in interfaces return ((allowedModes & PACKAGE_ALLOWED) != 0 && isSamePackage(defc, lookupClass)); case PRIVATE: ! // Rules for privates follows access rules for nestmates. ! boolean canAccess = ((allowedModes & PRIVATE) != 0 && ! Reflection.areNestMates(defc, lookupClass)); ! // FIX ME: Sanity check refc == defc. Either remove or convert to ! // plain assert before integration. ! myassert((canAccess && refc == defc) || !canAccess); ! return canAccess; default: throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods)); } } + static void myassert(boolean cond) { + if (!cond) throw new Error("Assertion failed"); + } static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) { return (refc == lookupClass || isSubClass(refc, lookupClass) || isSubClass(lookupClass, refc));
< prev index next >