1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang.reflect; 28 29 import java.lang.annotation.Annotation; 30 31 /** 32 * The AccessibleObject class is the base class for Field, Method and 33 * Constructor objects. It provides the ability to flag a reflected 34 * object as suppressing default Java language access control checks 35 * when it is used. The access checks--for public, default (package) 36 * access, protected, and private members--are performed when Fields, 37 * Methods or Constructors are used to set or get fields, to invoke 38 * methods, or to create and initialize new instances of classes, 39 * respectively. 40 * 41 * <p>Setting the {@code accessible} flag in a reflected object 42 * permits sophisticated applications with sufficient privilege, such 43 * as Java Object Serialization or other persistence mechanisms, to 44 * manipulate objects in a manner that would normally be prohibited. 45 * 46 * <p>By default, a reflected object is <em>not</em> accessible. 47 * 48 * @see Field 49 * @see Method 50 * @see Constructor 51 * @see ReflectPermission 52 * 53 * @since 1.2 54 */ 55 public class AccessibleObject implements AnnotatedElement { 56 57 /** 58 * Convenience method to set the {@code accessible} flag for an 59 * array of objects with a single security check (for efficiency). 60 * 61 * <p>First, if there is a security manager, its 62 * {@code checkPermission} method is called with a 63 * {@code ReflectPermission("suppressAccessChecks")} permission. 64 * 65 * <p>A {@code SecurityException} is raised if {@code flag} is 66 * {@code true} but accessibility of any of the elements of the input 67 * {@code array} may not be changed (for example, if the element 68 * object is a {@link Constructor} object for the class {@link 69 * java.lang.Class}). In the event of such a SecurityException, the 70 * accessibility of objects is set to {@code flag} for array elements 71 * upto (and excluding) the element for which the exception occurred; the 72 * accessibility of elements beyond (and including) the element for which 73 * the exception occurred is unchanged. 74 * 75 * @param array the array of AccessibleObjects 76 * @param flag the new value for the {@code accessible} flag 77 * in each object 78 * @throws SecurityException if the request is denied. 79 * @see SecurityManager#checkPermission 80 * @see java.lang.RuntimePermission 81 */ setAccessible(AccessibleObject[] array, boolean flag)82 public static void setAccessible(AccessibleObject[] array, boolean flag) 83 throws SecurityException { 84 for (int i = 0; i < array.length; i++) { 85 setAccessible0(array[i], flag); 86 } 87 } 88 89 /** 90 * Set the {@code accessible} flag for this object to 91 * the indicated boolean value. A value of {@code true} indicates that 92 * the reflected object should suppress Java language access 93 * checking when it is used. A value of {@code false} indicates 94 * that the reflected object should enforce Java language access checks. 95 * 96 * <p>First, if there is a security manager, its 97 * {@code checkPermission} method is called with a 98 * {@code ReflectPermission("suppressAccessChecks")} permission. 99 * 100 * <p>A {@code SecurityException} is raised if {@code flag} is 101 * {@code true} but accessibility of this object may not be changed 102 * (for example, if this element object is a {@link Constructor} object for 103 * the class {@link java.lang.Class}). 104 * 105 * <p>A {@code SecurityException} is raised if this object is a {@link 106 * java.lang.reflect.Constructor} object for the class 107 * {@code java.lang.Class}, and {@code flag} is true. 108 * 109 * @param flag the new value for the {@code accessible} flag 110 * @throws SecurityException if the request is denied. 111 * @see SecurityManager#checkPermission 112 * @see java.lang.RuntimePermission 113 */ setAccessible(boolean flag)114 public void setAccessible(boolean flag) throws SecurityException { 115 setAccessible0(this, flag); 116 } 117 118 /* Check that you aren't exposing java.lang.Class.<init> or sensitive 119 fields in java.lang.Class. */ setAccessible0(AccessibleObject obj, boolean flag)120 private static void setAccessible0(AccessibleObject obj, boolean flag) 121 throws SecurityException 122 { 123 if (obj instanceof Constructor && flag == true) { 124 Constructor<?> c = (Constructor<?>)obj; 125 // Android-changed: Added additional checks below. 126 Class<?> clazz = c.getDeclaringClass(); 127 if (c.getDeclaringClass() == Class.class) { 128 throw new SecurityException("Can not make a java.lang.Class" + 129 " constructor accessible"); 130 } else if (clazz == Method.class) { 131 throw new SecurityException("Can not make a java.lang.reflect.Method" + 132 " constructor accessible"); 133 } else if (clazz == Field.class) { 134 throw new SecurityException("Can not make a java.lang.reflect.Field" + 135 " constructor accessible"); 136 } 137 } 138 obj.override = flag; 139 } 140 141 /** 142 * Get the value of the {@code accessible} flag for this object. 143 * 144 * @return the value of the object's {@code accessible} flag 145 */ isAccessible()146 public boolean isAccessible() { 147 return override; 148 } 149 150 /** 151 * Constructor: only used by the Java Virtual Machine. 152 */ AccessibleObject()153 protected AccessibleObject() {} 154 155 // Indicates whether language-level access checks are overridden 156 // by this object. Initializes to "false". This field is used by 157 // Field, Method, and Constructor. 158 // 159 // NOTE: for security purposes, this field must not be visible 160 // outside this package. 161 boolean override; 162 163 /** 164 * @throws NullPointerException {@inheritDoc} 165 * @since 1.5 166 */ getAnnotation(Class<T> annotationClass)167 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 168 throw new AssertionError("All subclasses should override this method"); 169 } 170 171 /** 172 * {@inheritDoc} 173 * @throws NullPointerException {@inheritDoc} 174 * @since 1.5 175 */ 176 @Override isAnnotationPresent(Class<? extends Annotation> annotationClass)177 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { 178 return AnnotatedElement.super.isAnnotationPresent(annotationClass); 179 } 180 181 /** 182 * @throws NullPointerException {@inheritDoc} 183 * @since 1.8 184 */ 185 @Override getAnnotationsByType(Class<T> annotationClass)186 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { 187 throw new AssertionError("All subclasses should override this method"); 188 } 189 190 /** 191 * @since 1.5 192 */ getAnnotations()193 public Annotation[] getAnnotations() { 194 return getDeclaredAnnotations(); 195 } 196 197 /** 198 * @throws NullPointerException {@inheritDoc} 199 * @since 1.8 200 */ 201 @Override getDeclaredAnnotation(Class<T> annotationClass)202 public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { 203 // Only annotations on classes are inherited, for all other 204 // objects getDeclaredAnnotation is the same as 205 // getAnnotation. 206 return getAnnotation(annotationClass); 207 } 208 209 /** 210 * @throws NullPointerException {@inheritDoc} 211 * @since 1.8 212 */ 213 @Override getDeclaredAnnotationsByType(Class<T> annotationClass)214 public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { 215 // Only annotations on classes are inherited, for all other 216 // objects getDeclaredAnnotationsByType is the same as 217 // getAnnotationsByType. 218 return getAnnotationsByType(annotationClass); 219 } 220 221 /** 222 * @since 1.5 223 */ getDeclaredAnnotations()224 public Annotation[] getDeclaredAnnotations() { 225 throw new AssertionError("All subclasses should override this method"); 226 } 227 } 228