aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/lang/natClass.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang/natClass.cc')
-rw-r--r--libjava/java/lang/natClass.cc87
1 files changed, 58 insertions, 29 deletions
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
index 0db8228..4b08582 100644
--- a/libjava/java/lang/natClass.cc
+++ b/libjava/java/lang/natClass.cc
@@ -101,7 +101,7 @@ java::lang::Class::forName (jstring className)
{
klass = t->classAt (i);
}
- loader = klass->getClassLoader();
+ loader = klass->getClassLoaderInternal();
}
catch (::java::lang::ArrayIndexOutOfBoundsException *e)
{
@@ -113,13 +113,31 @@ java::lang::Class::forName (jstring className)
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
@@ -136,13 +154,14 @@ java::lang::Class::getClassLoader (void)
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))
{
@@ -163,7 +182,7 @@ java::lang::Class::getConstructor (JArray<jclass> *param_types)
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;
@@ -206,13 +225,14 @@ java::lang::Class::_getConstructors (jboolean declared)
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))
{
@@ -256,9 +276,7 @@ java::lang::Class::getField (jstring name, jint 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++)
{
@@ -277,9 +295,7 @@ java::lang::Class::getDeclaredField (jstring name)
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);
@@ -361,6 +377,8 @@ java::lang::Class::_getDeclaredMethod (jstring name,
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;
@@ -424,7 +442,7 @@ java::lang::Class::getClasses (void)
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
@@ -482,9 +500,7 @@ java::lang::Class::_getFields (JArray<java::lang::reflect::Field *> *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);
@@ -518,7 +534,6 @@ java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types)
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
@@ -642,7 +657,7 @@ java::lang::Class::getMethods (void)
{
using namespace java::lang::reflect;
- // FIXME: security checks.
+ memberAccessCheck(Member::PUBLIC);
// This will overestimate the size we need.
jint count = _getMethods (NULL, 0);
@@ -696,12 +711,7 @@ java::lang::Class::isInstance (jobject obj)
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 ()
@@ -1744,7 +1754,26 @@ _Jv_MakeVTable (jclass klass)
{
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 ();
+ }
}
}