| 1 | /* |
| 2 | * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. Oracle designates this |
| 8 | * particular file as subject to the "Classpath" exception as provided |
| 9 | * by Oracle in the LICENSE file that accompanied this code. |
| 10 | * |
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 14 | * version 2 for more details (a copy is included in the LICENSE file that |
| 15 | * accompanied this code). |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License version |
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | * |
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 22 | * or visit www.oracle.com if you need additional information or have any |
| 23 | * questions. |
| 24 | */ |
| 25 | |
| 26 | /*- |
| 27 | * Implementation of class Class |
| 28 | * |
| 29 | * former threadruntime.c, Sun Sep 22 12:09:39 1991 |
| 30 | */ |
| 31 | |
| 32 | #include <string.h> |
| 33 | #include <stdlib.h> |
| 34 | |
| 35 | #include "jni.h" |
| 36 | #include "jni_util.h" |
| 37 | #include "jvm.h" |
| 38 | #include "java_lang_Class.h" |
| 39 | |
| 40 | /* defined in libverify.so/verify.dll (src file common/check_format.c) */ |
| 41 | extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed); |
| 42 | extern jboolean VerifyFixClassname(char *utf_name); |
| 43 | |
| 44 | #define OBJ "Ljava/lang/Object;" |
| 45 | #define CLS "Ljava/lang/Class;" |
| 46 | #define CPL "Ljdk/internal/reflect/ConstantPool;" |
| 47 | #define STR "Ljava/lang/String;" |
| 48 | #define FLD "Ljava/lang/reflect/Field;" |
| 49 | #define MHD "Ljava/lang/reflect/Method;" |
| 50 | #define CTR "Ljava/lang/reflect/Constructor;" |
| 51 | #define PD "Ljava/security/ProtectionDomain;" |
| 52 | #define BA "[B" |
| 53 | |
| 54 | static JNINativeMethod methods[] = { |
| 55 | {"initClassName" , "()" STR, (void *)&JVM_InitClassName}, |
| 56 | {"getSuperclass" , "()" CLS, NULL}, |
| 57 | {"getInterfaces0" , "()[" CLS, (void *)&JVM_GetClassInterfaces}, |
| 58 | {"isInterface" , "()Z" , (void *)&JVM_IsInterface}, |
| 59 | {"getSigners" , "()[" OBJ, (void *)&JVM_GetClassSigners}, |
| 60 | {"setSigners" , "([" OBJ ")V" , (void *)&JVM_SetClassSigners}, |
| 61 | {"isArray" , "()Z" , (void *)&JVM_IsArrayClass}, |
| 62 | {"isPrimitive" , "()Z" , (void *)&JVM_IsPrimitiveClass}, |
| 63 | {"getModifiers" , "()I" , (void *)&JVM_GetClassModifiers}, |
| 64 | {"getDeclaredFields0" ,"(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields}, |
| 65 | {"getDeclaredMethods0" ,"(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods}, |
| 66 | {"getDeclaredConstructors0" ,"(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors}, |
| 67 | {"getProtectionDomain0" , "()" PD, (void *)&JVM_GetProtectionDomain}, |
| 68 | {"getDeclaredClasses0" , "()[" CLS, (void *)&JVM_GetDeclaredClasses}, |
| 69 | {"getDeclaringClass0" , "()" CLS, (void *)&JVM_GetDeclaringClass}, |
| 70 | {"getSimpleBinaryName0" , "()" STR, (void *)&JVM_GetSimpleBinaryName}, |
| 71 | {"getGenericSignature0" , "()" STR, (void *)&JVM_GetClassSignature}, |
| 72 | {"getRawAnnotations" , "()" BA, (void *)&JVM_GetClassAnnotations}, |
| 73 | {"getConstantPool" , "()" CPL, (void *)&JVM_GetClassConstantPool}, |
| 74 | {"desiredAssertionStatus0" ,"(" CLS")Z" , (void *)&JVM_DesiredAssertionStatus}, |
| 75 | {"getEnclosingMethod0" , "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo}, |
| 76 | {"getRawTypeAnnotations" , "()" BA, (void *)&JVM_GetClassTypeAnnotations}, |
| 77 | {"getNestHost0" , "()" CLS, (void *)&JVM_GetNestHost}, |
| 78 | {"getNestMembers0" , "()[" CLS, (void *)&JVM_GetNestMembers}, |
| 79 | }; |
| 80 | |
| 81 | #undef OBJ |
| 82 | #undef CLS |
| 83 | #undef STR |
| 84 | #undef FLD |
| 85 | #undef MHD |
| 86 | #undef CTR |
| 87 | #undef PD |
| 88 | |
| 89 | JNIEXPORT void JNICALL |
| 90 | Java_java_lang_Class_registerNatives(JNIEnv *env, jclass cls) |
| 91 | { |
| 92 | methods[1].fnPtr = (void *)(*env)->GetSuperclass; |
| 93 | (*env)->RegisterNatives(env, cls, methods, |
| 94 | sizeof(methods)/sizeof(JNINativeMethod)); |
| 95 | } |
| 96 | |
| 97 | JNIEXPORT jclass JNICALL |
| 98 | Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname, |
| 99 | jboolean initialize, jobject loader, jclass caller) |
| 100 | { |
| 101 | char *clname; |
| 102 | jclass cls = 0; |
| 103 | char buf[128]; |
| 104 | jsize len; |
| 105 | jsize unicode_len; |
| 106 | |
| 107 | if (classname == NULL) { |
| 108 | JNU_ThrowNullPointerException(env, 0); |
| 109 | return 0; |
| 110 | } |
| 111 | |
| 112 | len = (*env)->GetStringUTFLength(env, classname); |
| 113 | unicode_len = (*env)->GetStringLength(env, classname); |
| 114 | if (len >= (jsize)sizeof(buf)) { |
| 115 | clname = malloc(len + 1); |
| 116 | if (clname == NULL) { |
| 117 | JNU_ThrowOutOfMemoryError(env, NULL); |
| 118 | return NULL; |
| 119 | } |
| 120 | } else { |
| 121 | clname = buf; |
| 122 | } |
| 123 | (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname); |
| 124 | |
| 125 | if (VerifyFixClassname(clname) == JNI_TRUE) { |
| 126 | /* slashes present in clname, use name b4 translation for exception */ |
| 127 | (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname); |
| 128 | JNU_ThrowClassNotFoundException(env, clname); |
| 129 | goto done; |
| 130 | } |
| 131 | |
| 132 | if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */ |
| 133 | JNU_ThrowClassNotFoundException(env, clname); |
| 134 | goto done; |
| 135 | } |
| 136 | |
| 137 | cls = JVM_FindClassFromCaller(env, clname, initialize, loader, caller); |
| 138 | |
| 139 | done: |
| 140 | if (clname != buf) { |
| 141 | free(clname); |
| 142 | } |
| 143 | return cls; |
| 144 | } |
| 145 | |
| 146 | JNIEXPORT jboolean JNICALL |
| 147 | Java_java_lang_Class_isInstance(JNIEnv *env, jobject cls, jobject obj) |
| 148 | { |
| 149 | if (obj == NULL) { |
| 150 | return JNI_FALSE; |
| 151 | } |
| 152 | return (*env)->IsInstanceOf(env, obj, (jclass)cls); |
| 153 | } |
| 154 | |
| 155 | JNIEXPORT jboolean JNICALL |
| 156 | Java_java_lang_Class_isAssignableFrom(JNIEnv *env, jobject cls, jobject cls2) |
| 157 | { |
| 158 | if (cls2 == NULL) { |
| 159 | JNU_ThrowNullPointerException(env, 0); |
| 160 | return JNI_FALSE; |
| 161 | } |
| 162 | return (*env)->IsAssignableFrom(env, cls2, cls); |
| 163 | } |
| 164 | |
| 165 | JNIEXPORT jclass JNICALL |
| 166 | Java_java_lang_Class_getPrimitiveClass(JNIEnv *env, |
| 167 | jclass cls, |
| 168 | jstring name) |
| 169 | { |
| 170 | const char *utfName; |
| 171 | jclass result; |
| 172 | |
| 173 | if (name == NULL) { |
| 174 | JNU_ThrowNullPointerException(env, 0); |
| 175 | return NULL; |
| 176 | } |
| 177 | |
| 178 | utfName = (*env)->GetStringUTFChars(env, name, 0); |
| 179 | if (utfName == 0) |
| 180 | return NULL; |
| 181 | |
| 182 | result = JVM_FindPrimitiveClass(env, utfName); |
| 183 | |
| 184 | (*env)->ReleaseStringUTFChars(env, name, utfName); |
| 185 | |
| 186 | return result; |
| 187 | } |
| 188 | |