+ if (!access_is_accessible_member(callerclass, f->class, f->flags)) {
+ msglen =
+ utf_bytes(f->class->name) +
+ strlen(".") +
+ utf_bytes(f->name) +
+ strlen(" not accessible from ") +
+ utf_bytes(callerclass->name) +
+ strlen("0");
+
+ msg = MNEW(char, msglen);
+
+ utf_copy_classname(msg, f->class->name);
+ strcat(msg, ".");
+ utf_cat_classname(msg, f->name);
+ strcat(msg, " not accessible from ");
+ utf_cat_classname(msg, callerclass->name);
+
+ u = utf_new_char(msg);
+
+ MFREE(msg, char, msglen);
+
+ exceptions_throw_illegalaccessexception(u);
+
+ return false;
+ }
+
+ /* access granted */
+
+ return true;
+}
+
+
+/* access_check_method *********************************************************
+
+ Check if the (indirect) caller has access rights to the specified
+ method.
+
+ IN:
+ m................the method to check
+ calldepth........number of callers to ignore
+ For example if the stacktrace looks like this:
+
+ java.lang.reflect.Method.invokeNative (Native Method)
+ [0] java.lang.reflect.Method.invoke (Method.java:329)
+ [1] <caller>
+
+ you must specify 1 so the access rights of <caller>
+ are checked.
+
+ RETURN VALUE:
+ true.............access permitted
+ false............access denied, an exception has been thrown
+
+*******************************************************************************/
+
+bool access_check_method(methodinfo *m, s4 calldepth)
+{
+ java_handle_objectarray_t *oa;
+ classinfo *callerclass;
+ char *msg;
+ s4 msglen;
+ utf *u;
+
+ /* if everything is public, there is nothing to check */
+
+ if ((m->class->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
+ return true;
+
+ /* get the caller's class */
+
+ oa = stacktrace_getClassContext();
+
+ if (oa == NULL)
+ return false;
+
+ assert(calldepth >= 0 && calldepth < LLNI_array_size(oa));
+
+ callerclass = (classinfo *) oa->data[calldepth];
+
+ /* check access rights */
+
+ if (!access_is_accessible_member(callerclass, m->class, m->flags)) {
+ msglen =
+ utf_bytes(m->class->name) +
+ strlen(".") +
+ utf_bytes(m->name) +
+ utf_bytes(m->descriptor) +
+ strlen(" not accessible from ") +
+ utf_bytes(callerclass->name) +
+ strlen("0");
+
+ msg = MNEW(char, msglen);
+
+ utf_copy_classname(msg, m->class->name);
+ strcat(msg, ".");
+ utf_cat_classname(msg, m->name);
+ utf_cat_classname(msg, m->descriptor);
+ strcat(msg, " not accessible from ");
+ utf_cat_classname(msg, callerclass->name);
+
+ u = utf_new_char(msg);
+
+ MFREE(msg, char, msglen);
+
+ exceptions_throw_illegalaccessexception(u);
+