* src/vm/exceptions.h (exceptionptr): Removed.
[cacao.git] / src / vm / access.c
1 /* src/vm/access.c - checking access rights
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: access.c 7563 2007-03-23 21:33:53Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33
34 #include "vm/types.h"
35
36 #include "vm/access.h"
37 #include "vm/builtin.h"
38 #include "vm/exceptions.h"
39
40 #include "vm/jit/stacktrace.h"
41
42 #include "vmcore/class.h"
43
44
45 /****************************************************************************/
46 /* ACCESS CHECKS                                                            */
47 /****************************************************************************/
48
49 /* access_is_accessible_class **************************************************
50  
51    Check if a class is accessible from another class
52   
53    IN:
54        referer..........the class containing the reference
55        cls..............the result of resolving the reference
56   
57    RETURN VALUE:
58        true.............access permitted
59        false............access denied
60    
61    NOTE:
62        This function performs the checks listed in section 5.4.4.
63            "Access Control" of "The Java(TM) Virtual Machine Specification,
64            Second Edition".
65
66 *******************************************************************************/
67
68 bool access_is_accessible_class(classinfo *referer, classinfo *cls)
69 {
70         assert(referer);
71         assert(cls);
72
73         /* public classes are always accessible */
74
75         if (cls->flags & ACC_PUBLIC)
76                 return true;
77
78         /* a class in the same package is always accessible */
79
80         if (SAME_PACKAGE(referer, cls))
81                 return true;
82
83         /* a non-public class in another package is not accessible */
84
85         return false;
86 }
87
88
89 /* access_is_accessible_member *************************************************
90  
91    Check if a field or method is accessible from a given class
92   
93    IN:
94        referer..........the class containing the reference
95        declarer.........the class declaring the member
96        memberflags......the access flags of the member
97   
98    RETURN VALUE:
99        true.............access permitted
100        false............access denied
101
102    NOTE:
103        This function only performs the checks listed in section 5.4.4.
104            "Access Control" of "The Java(TM) Virtual Machine Specification,
105            Second Edition".
106
107            In particular a special condition for protected access with is
108            part of the verification process according to the spec is not
109            checked in this function.
110    
111 *******************************************************************************/
112
113 bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
114                                                                  s4 memberflags)
115 {
116         assert(referer);
117         assert(declarer);
118         
119         /* public members are accessible */
120
121         if (memberflags & ACC_PUBLIC)
122                 return true;
123
124         /* {declarer is not an interface} */
125
126         /* private members are only accessible by the class itself */
127
128         if (memberflags & ACC_PRIVATE)
129                 return (referer == declarer);
130
131         /* {the member is protected or package private} */
132
133         /* protected and package private members are accessible in the
134            same package */
135
136         if (SAME_PACKAGE(referer, declarer))
137                 return true;
138
139         /* package private members are not accessible outside the package */
140
141         if (!(memberflags & ACC_PROTECTED))
142                 return false;
143
144         /* {the member is protected and declarer is in another package} */
145
146         /* a necessary condition for access is that referer is a subclass
147            of declarer */
148
149         assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
150
151         if (class_isanysubclass(referer, declarer))
152                 return true;
153
154         return false;
155 }
156
157
158 /* access_check_member *********************************************************
159  
160    Check if the (indirect) caller has access rights to a member.
161   
162    IN:
163        declarer.........the class declaring the member
164        memberflags......the access flags of the member
165            calldepth........number of callers to ignore
166                             For example if the stacktrace looks like this:
167
168                                            java.lang.reflect.Method.invokeNative (Native Method)
169                                    [0] java.lang.reflect.Method.invoke (Method.java:329)
170                                    [1] <caller>
171
172                                         you must specify 1 so the access rights of <caller> 
173                                                 are checked.
174   
175    RETURN VALUE:
176        true.............access permitted
177        false............access denied, an exception has been thrown
178    
179 *******************************************************************************/
180
181 bool access_check_member(classinfo *declarer, s4 memberflags, s4 calldepth)
182 {
183         java_objectarray *oa;
184         classinfo        *callerclass;
185
186         /* if everything is public, there is nothing to check */
187
188         if ((declarer->flags & ACC_PUBLIC) && (memberflags & ACC_PUBLIC))
189                 return true;
190
191         /* get the caller's class */
192
193         oa = stacktrace_getClassContext();
194
195         if (oa == NULL)
196                 return false;
197
198         assert(calldepth >= 0 && calldepth < oa->header.size);
199
200         callerclass = (classinfo *) oa->data[calldepth];
201
202         /* check access rights */
203
204         if (!access_is_accessible_member(callerclass, declarer, memberflags)) {
205                 exceptions_throw_illegalaccessexception(callerclass);
206                 return false;
207         }
208
209         /* access granted */
210
211         return true;
212 }
213
214
215 /*
216  * These are local overrides for various environment variables in Emacs.
217  * Please do not remove this and leave it at the end of the file, where
218  * Emacs will automagically detect them.
219  * ---------------------------------------------------------------------
220  * Local variables:
221  * mode: c
222  * indent-tabs-mode: t
223  * c-basic-offset: 4
224  * tab-width: 4
225  * End:
226  * vim:noexpandtab:sw=4:ts=4:
227  */
228