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