{
klass = t->classAt (i);
}
- loader = klass->getClassLoader();
+ loader = klass->getClassLoaderInternal();
}
catch (::java::lang::ArrayIndexOutOfBoundsException *e)
{
java::lang::ClassLoader *
java::lang::Class::getClassLoader (void)
{
-#if 0
- // FIXME: the checks we need to do are more complex. See the spec.
- // Currently we can't implement them.
java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
if (s != NULL)
- s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
-#endif
+ {
+ gnu::gcj::runtime::StackTrace *t
+ = new gnu::gcj::runtime::StackTrace(4);
+ Class *caller = NULL;
+ ClassLoader *caller_loader = NULL;
+ try
+ {
+ for (int i = 1; !caller; i++)
+ {
+ caller = t->classAt (i);
+ }
+ caller_loader = caller->getClassLoaderInternal();
+ }
+ catch (::java::lang::ArrayIndexOutOfBoundsException *e)
+ {
+ }
+
+ // If the caller has a non-null class loader, and that loader
+ // is not this class' loader or an ancestor thereof, then do a
+ // security check.
+ if (caller_loader != NULL && ! caller_loader->isAncestorOf(loader))
+ s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
+ }
// The spec requires us to return `null' for primitive classes. In
// other cases we have the option of returning `null' for classes
java::lang::reflect::Constructor *
java::lang::Class::getConstructor (JArray<jclass> *param_types)
{
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
+
jstring partial_sig = getSignature (param_types, true);
jint hash = partial_sig->hashCode ();
int i = isPrimitive () ? 0 : method_count;
while (--i >= 0)
{
- // FIXME: access checks.
if (_Jv_equalUtf8Consts (methods[i].name, init_name)
&& _Jv_equal (methods[i].signature, partial_sig, hash))
{
JArray<java::lang::reflect::Constructor *> *
java::lang::Class::_getConstructors (jboolean declared)
{
- // FIXME: this method needs access checks.
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
int numConstructors = 0;
int max = isPrimitive () ? 0 : method_count;
java::lang::reflect::Constructor *
java::lang::Class::getDeclaredConstructor (JArray<jclass> *param_types)
{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
jstring partial_sig = getSignature (param_types, true);
jint hash = partial_sig->hashCode ();
int i = isPrimitive () ? 0 : method_count;
while (--i >= 0)
{
- // FIXME: access checks.
if (_Jv_equalUtf8Consts (methods[i].name, init_name)
&& _Jv_equal (methods[i].signature, partial_sig, hash))
{
java::lang::reflect::Field *
java::lang::Class::getDeclaredField (jstring name)
{
- java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
- if (s != NULL)
- s->checkMemberAccess (this, java::lang::reflect::Member::DECLARED);
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
int hash = name->hashCode();
for (int i = 0; i < field_count; i++)
{
JArray<java::lang::reflect::Field *> *
java::lang::Class::getDeclaredFields (void)
{
- java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
- if (s != NULL)
- s->checkMemberAccess (this, java::lang::reflect::Member::DECLARED);
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
JArray<java::lang::reflect::Field *> *result
= (JArray<java::lang::reflect::Field *> *)
JvNewObjectArray (field_count, &java::lang::reflect::Field::class$, NULL);
JArray<java::lang::reflect::Method *> *
java::lang::Class::getDeclaredMethods (void)
{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
int numMethods = 0;
int max = isPrimitive () ? 0 : method_count;
int i;
JArray<jclass> *
java::lang::Class::getDeclaredClasses (void)
{
- checkMemberAccess (java::lang::reflect::Member::DECLARED);
+ memberAccessCheck (java::lang::reflect::Member::DECLARED);
// Until we have inner classes, it always makes sense to return an
// empty array.
JArray<jclass> *result
JArray<java::lang::reflect::Field *> *
java::lang::Class::getFields (void)
{
- // FIXME: security checking.
-
- using namespace java::lang::reflect;
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
int count = _getFields (NULL, 0);
int i = klass->isPrimitive () ? 0 : klass->method_count;
while (--i >= 0)
{
- // FIXME: access checks.
if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
&& _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)
&& (klass->methods[i].accflags
{
using namespace java::lang::reflect;
- // FIXME: security checks.
+ memberAccessCheck(Member::PUBLIC);
// This will overestimate the size we need.
jint count = _getMethods (NULL, 0);
jobject
java::lang::Class::newInstance (void)
{
- // FIXME: do accessibility checks here. There currently doesn't
- // seem to be any way to do these.
- // FIXME: we special-case one check here just to pass a Plum Hall
- // test. Once access checking is implemented, remove this.
- if (this == &java::lang::Class::class$)
- throw new java::lang::IllegalAccessException;
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
if (isPrimitive ()
|| isInterface ()
{
for (int i = 0; i < klass->vtable_method_count; ++i)
if (! flags[i])
- // FIXME: messsage.
- throw new java::lang::AbstractMethodError ();
+ {
+ using namespace java::lang;
+ while (klass != NULL)
+ {
+ for (int j = 0; j < klass->method_count; ++j)
+ {
+ if (klass->methods[i].index == i)
+ {
+ StringBuffer *buf = new StringBuffer ();
+ buf->append (_Jv_NewStringUtf8Const (klass->methods[i].name));
+ buf->append ((jchar) ' ');
+ buf->append (_Jv_NewStringUtf8Const (klass->methods[i].signature));
+ throw new AbstractMethodError (buf->toString ());
+ }
+ }
+ klass = klass->getSuperclass ();
+ }
+ // Couldn't find the name, which is weird.
+ // But we still must throw the error.
+ throw new AbstractMethodError ();
+ }
}
}