96 * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
97 * Do not store it in place where untrusted code can access it.
98 * <p>
99 * This method is caller sensitive, which means that it may return different
100 * values to different callers.
101 * <p>
102 * For any given caller class {@code C}, the lookup object returned by this call
103 * has equivalent capabilities to any lookup object
104 * supplied by the JVM to the bootstrap method of an
105 * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
106 * executing in the same caller class {@code C}.
107 * @return a lookup object for the caller of this method, with private access
108 */
109 @CallerSensitive
110 @ForceInline // to ensure Reflection.getCallerClass optimization
111 public static Lookup lookup() {
112 return new Lookup(Reflection.getCallerClass());
113 }
114
115 /**
116 * Returns a {@link Lookup lookup object} which is trusted minimally.
117 * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes.
118 * It can only be used to create method handles to public members of
119 * public classes in packages that are exported unconditionally.
120 * <p>
121 * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
122 * of this lookup object will be {@link java.lang.Object}.
123 *
124 * @apiNote The use of Object is conventional, and because the lookup modes are
125 * limited, there is no special access provided to the internals of Object, its package
126 * or its module. Consequently, the lookup context of this lookup object will be the
127 * bootstrap class loader, which means it cannot find user classes.
128 *
129 * <p style="font-size:smaller;">
130 * <em>Discussion:</em>
131 * The lookup class can be changed to any other class {@code C} using an expression of the form
132 * {@link Lookup#in publicLookup().in(C.class)}.
133 * but may change the lookup context by virtue of changing the class loader.
134 * A public lookup object is always subject to
135 * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
730 * lookup object, and also by the new lookup class.
731 * @return the lookup modes, which limit the kinds of access performed by this lookup object
732 * @see #in
733 * @see #dropLookupMode
734 *
735 * @revised 9
736 * @spec JPMS
737 */
738 public int lookupModes() {
739 return allowedModes & ALL_MODES;
740 }
741
742 /** Embody the current class (the lookupClass) as a lookup class
743 * for method handle creation.
744 * Must be called by from a method in this package,
745 * which in turn is called by a method not in this package.
746 */
747 Lookup(Class<?> lookupClass) {
748 this(lookupClass, FULL_POWER_MODES);
749 // make sure we haven't accidentally picked up a privileged class:
750 checkUnprivilegedlookupClass(lookupClass, FULL_POWER_MODES);
751 }
752
753 private Lookup(Class<?> lookupClass, int allowedModes) {
754 this.lookupClass = lookupClass;
755 this.allowedModes = allowedModes;
756 }
757
758 /**
759 * Creates a lookup on the specified new lookup class.
760 * The resulting object will report the specified
761 * class as its own {@link #lookupClass lookupClass}.
762 * <p>
763 * However, the resulting {@code Lookup} object is guaranteed
764 * to have no more access capabilities than the original.
765 * In particular, access capabilities can be lost as follows:<ul>
766 * <li>If the old lookup class is in a {@link Module#isNamed() named} module, and
767 * the new lookup class is in a different module {@code M}, then no members, not
768 * even public members in {@code M}'s exported packages, will be accessible.
769 * The exception to this is when this lookup is {@link #publicLookup()
770 * publicLookup}, in which case {@code PUBLIC} access is not lost.
810 newModes = 0;
811 else
812 newModes &= ~(MODULE|PACKAGE|PRIVATE|PROTECTED);
813 }
814 if ((newModes & PACKAGE) != 0
815 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
816 newModes &= ~(PACKAGE|PRIVATE|PROTECTED);
817 }
818 // Allow nestmate lookups to be created without special privilege:
819 if ((newModes & PRIVATE) != 0
820 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
821 newModes &= ~(PRIVATE|PROTECTED);
822 }
823 if ((newModes & PUBLIC) != 0
824 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
825 // The requested class it not accessible from the lookup class.
826 // No permissions.
827 newModes = 0;
828 }
829
830 checkUnprivilegedlookupClass(requestedLookupClass, newModes);
831 return new Lookup(requestedLookupClass, newModes);
832 }
833
834
835 /**
836 * Creates a lookup on the same lookup class which this lookup object
837 * finds members, but with a lookup mode that has lost the given lookup mode.
838 * The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
839 * MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
840 * {@link #PROTECTED PROTECTED} and {@link #UNCONDITIONAL UNCONDITIONAL} are always
841 * dropped and so the resulting lookup mode will never have these access capabilities.
842 * When dropping {@code PACKAGE} then the resulting lookup will not have {@code PACKAGE}
843 * or {@code PRIVATE} access. When dropping {@code MODULE} then the resulting lookup will
844 * not have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code PUBLIC}
845 * is dropped then the resulting lookup has no access.
846 * @param modeToDrop the lookup mode to drop
847 * @return a lookup object which lacks the indicated mode, or the same object if there is no change
848 * @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
849 * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
850 * @see MethodHandles#privateLookupIn
967 PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
968 return AccessController.doPrivileged(pa);
969 }
970
971 // cached protection domain
972 private volatile ProtectionDomain cachedProtectionDomain;
973
974
975 // Make sure outer class is initialized first.
976 static { IMPL_NAMES.getClass(); }
977
978 /** Package-private version of lookup which is trusted. */
979 static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
980
981 /** Version of lookup which is trusted minimally.
982 * It can only be used to create method handles to publicly accessible
983 * members in packages that are exported unconditionally.
984 */
985 static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
986
987 private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
988 String name = lookupClass.getName();
989 if (name.startsWith("java.lang.invoke."))
990 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
991
992 // For caller-sensitive MethodHandles.lookup() disallow lookup from
993 // restricted packages. This a fragile and blunt approach.
994 // TODO replace with a more formal and less fragile mechanism
995 // that does not bluntly restrict classes under packages within
996 // java.base from looking up MethodHandles or VarHandles.
997 if (allowedModes == FULL_POWER_MODES && lookupClass.getClassLoader() == null) {
998 if ((name.startsWith("java.") &&
999 !name.equals("java.lang.Thread") &&
1000 !name.startsWith("java.util.concurrent.")) ||
1001 (name.startsWith("sun.") &&
1002 !name.startsWith("sun.invoke."))) {
1003 throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
1004 }
1005 }
1006 }
1007
1008 /**
1009 * Displays the name of the class from which lookups are to be made.
1010 * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
1011 * If there are restrictions on the access permitted to this lookup,
1012 * this is indicated by adding a suffix to the class name, consisting
1013 * of a slash and a keyword. The keyword represents the strongest
1014 * allowed access, and is chosen as follows:
1015 * <ul>
1016 * <li>If no access is allowed, the suffix is "/noaccess".
1017 * <li>If only public access to types in exported packages is allowed, the suffix is "/public".
1018 * <li>If only public access and unconditional access are allowed, the suffix is "/publicLookup".
1019 * <li>If only public and module access are allowed, the suffix is "/module".
1020 * <li>If only public, module and package access are allowed, the suffix is "/package".
1021 * <li>If only public, module, package, and private access are allowed, the suffix is "/private".
1022 * </ul>
1023 * If none of the above cases apply, it is the case that full
1024 * access (public, module, package, private, and protected) is allowed.
1025 * In this case, no suffix is added.
|
96 * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
97 * Do not store it in place where untrusted code can access it.
98 * <p>
99 * This method is caller sensitive, which means that it may return different
100 * values to different callers.
101 * <p>
102 * For any given caller class {@code C}, the lookup object returned by this call
103 * has equivalent capabilities to any lookup object
104 * supplied by the JVM to the bootstrap method of an
105 * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
106 * executing in the same caller class {@code C}.
107 * @return a lookup object for the caller of this method, with private access
108 */
109 @CallerSensitive
110 @ForceInline // to ensure Reflection.getCallerClass optimization
111 public static Lookup lookup() {
112 return new Lookup(Reflection.getCallerClass());
113 }
114
115 /**
116 * This reflected$lookup method is the alternate implementation of
117 * the lookup method when being invoked by reflection.
118 */
119 @CallerSensitive
120 private static Lookup reflected$lookup() {
121 Class<?> caller = Reflection.getCallerClass();
122 if (caller.getClassLoader() == null) {
123 throw newIllegalArgumentException("illegal lookupClass: "+caller);
124 }
125 return new Lookup(caller);
126 }
127
128 /**
129 * Returns a {@link Lookup lookup object} which is trusted minimally.
130 * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes.
131 * It can only be used to create method handles to public members of
132 * public classes in packages that are exported unconditionally.
133 * <p>
134 * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
135 * of this lookup object will be {@link java.lang.Object}.
136 *
137 * @apiNote The use of Object is conventional, and because the lookup modes are
138 * limited, there is no special access provided to the internals of Object, its package
139 * or its module. Consequently, the lookup context of this lookup object will be the
140 * bootstrap class loader, which means it cannot find user classes.
141 *
142 * <p style="font-size:smaller;">
143 * <em>Discussion:</em>
144 * The lookup class can be changed to any other class {@code C} using an expression of the form
145 * {@link Lookup#in publicLookup().in(C.class)}.
146 * but may change the lookup context by virtue of changing the class loader.
147 * A public lookup object is always subject to
148 * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
743 * lookup object, and also by the new lookup class.
744 * @return the lookup modes, which limit the kinds of access performed by this lookup object
745 * @see #in
746 * @see #dropLookupMode
747 *
748 * @revised 9
749 * @spec JPMS
750 */
751 public int lookupModes() {
752 return allowedModes & ALL_MODES;
753 }
754
755 /** Embody the current class (the lookupClass) as a lookup class
756 * for method handle creation.
757 * Must be called by from a method in this package,
758 * which in turn is called by a method not in this package.
759 */
760 Lookup(Class<?> lookupClass) {
761 this(lookupClass, FULL_POWER_MODES);
762 // make sure we haven't accidentally picked up a privileged class:
763 checkUnprivilegedlookupClass(lookupClass);
764 }
765
766 private Lookup(Class<?> lookupClass, int allowedModes) {
767 this.lookupClass = lookupClass;
768 this.allowedModes = allowedModes;
769 }
770
771 /**
772 * Creates a lookup on the specified new lookup class.
773 * The resulting object will report the specified
774 * class as its own {@link #lookupClass lookupClass}.
775 * <p>
776 * However, the resulting {@code Lookup} object is guaranteed
777 * to have no more access capabilities than the original.
778 * In particular, access capabilities can be lost as follows:<ul>
779 * <li>If the old lookup class is in a {@link Module#isNamed() named} module, and
780 * the new lookup class is in a different module {@code M}, then no members, not
781 * even public members in {@code M}'s exported packages, will be accessible.
782 * The exception to this is when this lookup is {@link #publicLookup()
783 * publicLookup}, in which case {@code PUBLIC} access is not lost.
823 newModes = 0;
824 else
825 newModes &= ~(MODULE|PACKAGE|PRIVATE|PROTECTED);
826 }
827 if ((newModes & PACKAGE) != 0
828 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
829 newModes &= ~(PACKAGE|PRIVATE|PROTECTED);
830 }
831 // Allow nestmate lookups to be created without special privilege:
832 if ((newModes & PRIVATE) != 0
833 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
834 newModes &= ~(PRIVATE|PROTECTED);
835 }
836 if ((newModes & PUBLIC) != 0
837 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
838 // The requested class it not accessible from the lookup class.
839 // No permissions.
840 newModes = 0;
841 }
842
843 checkUnprivilegedlookupClass(requestedLookupClass);
844 return new Lookup(requestedLookupClass, newModes);
845 }
846
847
848 /**
849 * Creates a lookup on the same lookup class which this lookup object
850 * finds members, but with a lookup mode that has lost the given lookup mode.
851 * The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
852 * MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
853 * {@link #PROTECTED PROTECTED} and {@link #UNCONDITIONAL UNCONDITIONAL} are always
854 * dropped and so the resulting lookup mode will never have these access capabilities.
855 * When dropping {@code PACKAGE} then the resulting lookup will not have {@code PACKAGE}
856 * or {@code PRIVATE} access. When dropping {@code MODULE} then the resulting lookup will
857 * not have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code PUBLIC}
858 * is dropped then the resulting lookup has no access.
859 * @param modeToDrop the lookup mode to drop
860 * @return a lookup object which lacks the indicated mode, or the same object if there is no change
861 * @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
862 * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
863 * @see MethodHandles#privateLookupIn
980 PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
981 return AccessController.doPrivileged(pa);
982 }
983
984 // cached protection domain
985 private volatile ProtectionDomain cachedProtectionDomain;
986
987
988 // Make sure outer class is initialized first.
989 static { IMPL_NAMES.getClass(); }
990
991 /** Package-private version of lookup which is trusted. */
992 static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
993
994 /** Version of lookup which is trusted minimally.
995 * It can only be used to create method handles to publicly accessible
996 * members in packages that are exported unconditionally.
997 */
998 static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
999
1000 private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
1001 String name = lookupClass.getName();
1002 if (name.startsWith("java.lang.invoke."))
1003 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
1004 }
1005
1006 /**
1007 * Displays the name of the class from which lookups are to be made.
1008 * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
1009 * If there are restrictions on the access permitted to this lookup,
1010 * this is indicated by adding a suffix to the class name, consisting
1011 * of a slash and a keyword. The keyword represents the strongest
1012 * allowed access, and is chosen as follows:
1013 * <ul>
1014 * <li>If no access is allowed, the suffix is "/noaccess".
1015 * <li>If only public access to types in exported packages is allowed, the suffix is "/public".
1016 * <li>If only public access and unconditional access are allowed, the suffix is "/publicLookup".
1017 * <li>If only public and module access are allowed, the suffix is "/module".
1018 * <li>If only public, module and package access are allowed, the suffix is "/package".
1019 * <li>If only public, module, package, and private access are allowed, the suffix is "/private".
1020 * </ul>
1021 * If none of the above cases apply, it is the case that full
1022 * access (public, module, package, private, and protected) is allowed.
1023 * In this case, no suffix is added.
|