1 /* 2 * Copyright (c) 2015, 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 #include <stdlib.h> 26 #include <string.h> 27 28 #include "jni.h" 29 #include "jni_util.h" 30 #include "jvm.h" 31 32 #include "java_lang_reflect_Module.h" 33 34 /* 35 * Gets the UTF-8 chars for the string and translates '.' to '/'. Does no 36 * further validation, assumption being that both calling code in 37 * java.lang.reflect.Module and VM will do deeper validation. 38 */ 39 static char* 40 GetInternalPackageName(JNIEnv *env, jstring pkg, char* buf, jsize buf_size) 41 { 42 jsize len; 43 jsize unicode_len; 44 char* p; 45 char* utf_str; 46 47 len = (*env)->GetStringUTFLength(env, pkg); 48 unicode_len = (*env)->GetStringLength(env, pkg); 49 if (len >= buf_size) { 50 utf_str = malloc(len + 1); 51 if (utf_str == NULL) { 52 JNU_ThrowOutOfMemoryError(env, NULL); 53 return NULL; 54 } 55 } else { 56 utf_str = buf; 57 } 58 (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, utf_str); 59 60 p = utf_str; 61 while (*p != '\0') { 62 if (*p == '.') { 63 *p = '/'; 64 } 65 p++; 66 } 67 return utf_str; 68 } 69 70 JNIEXPORT void JNICALL 71 Java_java_lang_reflect_Module_defineModule0(JNIEnv *env, jclass cls, jobject module, 72 jboolean is_open, jstring version, 73 jstring location, jobjectArray packages) 74 { 75 char** pkgs = NULL; 76 jsize idx; 77 jsize num_packages = (*env)->GetArrayLength(env, packages); 78 79 if (num_packages != 0 && (pkgs = calloc(num_packages, sizeof(char*))) == NULL) { 80 JNU_ThrowOutOfMemoryError(env, NULL); 81 return; 82 } else { 83 int valid = 1; 84 for (idx = 0; idx < num_packages; idx++) { 85 jstring pkg = (*env)->GetObjectArrayElement(env, packages, idx); 86 pkgs[idx] = GetInternalPackageName(env, pkg, NULL, 0); 87 if (pkgs[idx] == NULL) { 88 valid = 0; 89 break; 90 } 91 } 92 93 if (valid != 0) { 94 JVM_DefineModule(env, module, is_open, version, location, 95 (const char* const*)pkgs, num_packages); 96 } 97 } 98 99 if (num_packages > 0) { 100 for (idx = 0; idx < num_packages; idx++) { 101 if (pkgs[idx] != NULL) { 102 free(pkgs[idx]); 103 } 104 } 105 free(pkgs); 106 } 107 } 108 109 JNIEXPORT void JNICALL 110 Java_java_lang_reflect_Module_addReads0(JNIEnv *env, jclass cls, jobject from, jobject to) 111 { 112 JVM_AddReadsModule(env, from, to); 113 } 114 115 JNIEXPORT void JNICALL 116 Java_java_lang_reflect_Module_addExports0(JNIEnv *env, jclass cls, jobject from, 117 jstring pkg, jobject to) 118 { 119 char buf[128]; 120 char* pkg_name; 121 122 if (pkg == NULL) { 123 JNU_ThrowNullPointerException(env, "package is null"); 124 return; 125 } 126 127 pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); 128 if (pkg_name != NULL) { 129 JVM_AddModuleExports(env, from, pkg_name, to); 130 if (pkg_name != buf) { 131 free(pkg_name); 132 } 133 } 134 } 135 136 JNIEXPORT void JNICALL 137 Java_java_lang_reflect_Module_addExportsToAll0(JNIEnv *env, jclass cls, jobject from, 138 jstring pkg) 139 { 140 char buf[128]; 141 char* pkg_name; 142 143 if (pkg == NULL) { 144 JNU_ThrowNullPointerException(env, "package is null"); 145 return; 146 } 147 148 pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); 149 if (pkg_name != NULL) { 150 JVM_AddModuleExportsToAll(env, from, pkg_name); 151 if (pkg_name != buf) { 152 free(pkg_name); 153 } 154 } 155 } 156 157 JNIEXPORT void JNICALL 158 Java_java_lang_reflect_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls, 159 jobject from, jstring pkg) 160 { 161 char buf[128]; 162 char* pkg_name; 163 164 if (pkg == NULL) { 165 JNU_ThrowNullPointerException(env, "package is null"); 166 return; 167 } 168 169 pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); 170 if (pkg_name != NULL) { 171 JVM_AddModuleExportsToAllUnnamed(env, from, pkg_name); 172 if (pkg_name != buf) { 173 free(pkg_name); 174 } 175 } 176 } 177 178 JNIEXPORT void JNICALL 179 Java_java_lang_reflect_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg) 180 { 181 char buf[128]; 182 char* pkg_name; 183 184 if (pkg == NULL) { 185 JNU_ThrowNullPointerException(env, "package is null"); 186 return; 187 } 188 189 pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); 190 if (pkg_name != NULL) { 191 JVM_AddModulePackage(env, m, pkg_name); 192 if (pkg_name != buf) { 193 free(pkg_name); 194 } 195 } 196 }