< prev index next >

test/java/lang/invoke/AccessControlTest.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2012, 2016, 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. --- 1,7 ---- /* ! * Copyright (c) 2012, 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.
*** 116,125 **** --- 116,127 ---- String suffix = ""; if (lookupModes == 0) suffix = "/noaccess"; else if (lookupModes == PUBLIC) suffix = "/public"; + else if (lookupModes == (PUBLIC|UNCONDITIONAL)) + suffix = "/publicLookup"; else if (lookupModes == (PUBLIC|MODULE)) suffix = "/module"; else if (lookupModes == (PUBLIC|MODULE|PACKAGE)) suffix = "/package"; else if (lookupModes == (PUBLIC|MODULE|PACKAGE|PRIVATE))
*** 138,164 **** * class as its own {@link #lookupClass lookupClass}. * <p> * [A2] However, the resulting {@code Lookup} object is guaranteed * to have no more access capabilities than the original. * In particular, access capabilities can be lost as follows:<ul> ! * <li>[A3] If the new lookup class differs from the old one, ! * protected members will not be accessible by virtue of inheritance. * (Protected members may continue to be accessible because of package sharing.) ! * <li>[A4] If the new lookup class is in a different package ! * than the old one, protected and default (package) members will not be accessible. ! * <li>[A5] If the new lookup class is not within the same package member * as the old one, private members will not be accessible. ! * <li>[A6] If the new lookup class is not accessible to the old lookup class, ! * using the original access modes, * then no members, not even public members, will be accessible. ! * <li>[A7] If the new lookup class for this {@code Lookup} is in the unnamed module, ! * and the new lookup class is in a named module {@code M}, then no members in ! * {@code M}'s non-exported packages will be accessible. ! * <li>[A8] If the lookup for this {@code Lookup} is in a named module, and the ! * new lookup class is in a different module, then no members, not even ! * public members in {@code M}'s exported packages, will be accessible. ! * [A8] (In all other cases, public members will continue to be accessible.) * </ul> * Other than the above cases, the new lookup will have the same * access capabilities as the original. [A10] * <hr> */ --- 140,167 ---- * class as its own {@link #lookupClass lookupClass}. * <p> * [A2] However, the resulting {@code Lookup} object is guaranteed * to have no more access capabilities than the original. * In particular, access capabilities can be lost as follows:<ul> ! * <li> [A3] If the old lookup class is in a named module, and the new ! * lookup class is in a different module {@code M}, then no members, not ! * even public members in {@code M}'s exported packages, will be accessible. ! * The exception to this is when this lookup is publicLookup, in which case ! * public access is not lost. ! * <li> [A4] If the old lookup class is in an unnamed module, and the new ! * lookup class is a different module then module access is lost. ! * <li> [A5] If the new lookup class differs from the old one then UNCONDITIONAL ! * is lost. If the new lookup class is not within the same package member as the ! * old one, protected members will not be accessible by virtue of inheritance. * (Protected members may continue to be accessible because of package sharing.) ! * <li> [A6] If the new lookup class is in a different package than the old one, ! * protected and default (package) members will not be accessible. ! * <li> [A7] If the new lookup class is not within the same package member * as the old one, private members will not be accessible. ! * <li> [A8] If the new lookup class is not accessible to the old lookup class, * then no members, not even public members, will be accessible. ! * <li> [A9] (In all other cases, public members will continue to be accessible.) * </ul> * Other than the above cases, the new lookup will have the same * access capabilities as the original. [A10] * <hr> */
*** 169,208 **** // for the purposes of access control then treat classes in different unnamed // modules as being in the same module. boolean sameModule = (c1.getModule() == c2.getModule()) || (!c1.getModule().isNamed() && !c2.getModule().isNamed()); boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() && ! packagePrefix(c1).equals(packagePrefix(c2))); boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2)); boolean sameClass = (c1 == c2); assert(samePackage || !sameTopLevel); assert(sameTopLevel || !sameClass); ! boolean accessible = sameClass; // [A6] if ((m1 & PACKAGE) != 0) accessible |= samePackage; if ((m1 & PUBLIC ) != 0) accessible |= (c2.getModifiers() & PUBLIC) != 0; if (!sameModule) { ! if (c1.getModule().isNamed()) { ! accessible = false; // [A8] } else { ! // Different module; loose MODULE and lower access. ! changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED); // [A7] } } if (!accessible) { // Different package and no access to c2; lose all access. ! changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED); // [A6] } if (!samePackage) { // Different package; loose PACKAGE and lower access. ! changed |= (PACKAGE|PRIVATE|PROTECTED); // [A4] } if (!sameTopLevel) { ! // Different top-level class. Lose PRIVATE and lower access. ! changed |= (PRIVATE|PROTECTED); // [A5] } if (!sameClass) { ! changed |= (PROTECTED); // [A3] } else { assert(changed == 0); // [A10] (no deprivation if same class) } if (accessible) assert((changed & PUBLIC) == 0); // [A9] int m2 = m1 & ~changed; --- 172,210 ---- // for the purposes of access control then treat classes in different unnamed // modules as being in the same module. boolean sameModule = (c1.getModule() == c2.getModule()) || (!c1.getModule().isNamed() && !c2.getModule().isNamed()); boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() && ! c1.getPackageName().equals(c2.getPackageName())); boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2)); boolean sameClass = (c1 == c2); assert(samePackage || !sameTopLevel); assert(sameTopLevel || !sameClass); ! boolean accessible = sameClass; if ((m1 & PACKAGE) != 0) accessible |= samePackage; if ((m1 & PUBLIC ) != 0) accessible |= (c2.getModifiers() & PUBLIC) != 0; if (!sameModule) { ! if (c1.getModule().isNamed() && (m1 & UNCONDITIONAL) == 0) { ! accessible = false; // [A3] } else { ! changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED); // [A3] [A4] } } if (!accessible) { // Different package and no access to c2; lose all access. ! changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED); // [A8] } if (!samePackage) { // Different package; loose PACKAGE and lower access. ! changed |= (PACKAGE|PRIVATE|PROTECTED); // [A6] } if (!sameTopLevel) { ! // Different top-level class. Lose PRIVATE and PROTECTED access. ! changed |= (PRIVATE|PROTECTED); // [A5] [A7] } if (!sameClass) { ! changed |= (UNCONDITIONAL); // [A5] } else { assert(changed == 0); // [A10] (no deprivation if same class) } if (accessible) assert((changed & PUBLIC) == 0); // [A9] int m2 = m1 & ~changed;
*** 226,240 **** /** Predict the success or failure of accessing this method. */ public boolean willAccess(Method m) { Class<?> c1 = lookupClass(); Class<?> c2 = m.getDeclaringClass(); ! // if the lookup class is in a loose module with PUBLIC access then ! // public members of public types in all unnamed modules can be accessed ! if (isLooseModule(c1.getModule()) && (lookupModes & PUBLIC) != 0 ! && (!c2.getModule().isNamed()) && Modifier.isPublic(c2.getModifiers()) && Modifier.isPublic(m.getModifiers())) return true; LookupCase lc = this.in(c2); --- 228,241 ---- /** Predict the success or failure of accessing this method. */ public boolean willAccess(Method m) { Class<?> c1 = lookupClass(); Class<?> c2 = m.getDeclaringClass(); ! // publicLookup has access to all public types/members of types in unnamed modules ! if ((lookupModes & UNCONDITIONAL) != 0 && (lookupModes & PUBLIC) != 0 ! && !c2.getModule().isNamed() && Modifier.isPublic(c2.getModifiers()) && Modifier.isPublic(m.getModifiers())) return true; LookupCase lc = this.in(c2);
*** 261,279 **** if (load && c2.getClassLoader() != null) { if (c1.getClassLoader() == null) { // not visible return false; } - if (c1 == publicLookup().lookupClass()) { - // not visible as lookup class is defined by child of the boot loader - return false; - } } ! // if the lookup class is in a loose module with PUBLIC access then ! // public types in all unnamed modules can be accessed ! if (isLooseModule(c1.getModule()) && (lookupModes & PUBLIC) != 0 && (!c2.getModule().isNamed()) && Modifier.isPublic(c2.getModifiers())) return true; --- 262,275 ---- if (load && c2.getClassLoader() != null) { if (c1.getClassLoader() == null) { // not visible return false; } } ! // publicLookup has access to all public types/members of types in unnamed modules ! if ((lookupModes & UNCONDITIONAL) != 0 && (lookupModes & PUBLIC) != 0 && (!c2.getModule().isNamed()) && Modifier.isPublic(c2.getModifiers())) return true;
*** 293,307 **** if (verbosity >= 2) { System.out.println(this+" willAccessClass "+lc+" c1="+c1+" c2="+c2+" => "+r); } return r; } - - private boolean isLooseModule(Module m) { - ClassLoader cl = new ClassLoader() { }; - return m.canRead(cl.getUnnamedModule()); - } } private static Class<?> topLevelClass(Class<?> cls) { Class<?> c = cls; for (Class<?> ec; (ec = c.getEnclosingClass()) != null; ) --- 289,298 ----
*** 309,326 **** assert(c.getEnclosingClass() == null); assert(c == cls || cls.getEnclosingClass() != null); return c; } - private static String packagePrefix(Class<?> c) { - while (c.isArray()) c = c.getComponentType(); - String s = c.getName(); - assert(s.indexOf('/') < 0); - return s.substring(0, s.lastIndexOf('.')+1); - } - - private final TreeSet<LookupCase> CASES = new TreeSet<>(); private final TreeMap<LookupCase,TreeSet<LookupCase>> CASE_EDGES = new TreeMap<>(); private final ArrayList<ClassLoader> LOADERS = new ArrayList<>(); private final ClassLoader THIS_LOADER = this.getClass().getClassLoader(); { if (THIS_LOADER != null) LOADERS.add(THIS_LOADER); } // #1 --- 300,309 ----
< prev index next >