1 /* 2 * Copyright (c) 2015, 2017, 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_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.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_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 num_packages = (*env)->GetArrayLength(env, packages); 77 78 if (num_packages != 0 && (pkgs = calloc(num_packages, sizeof(char*))) == NULL) { 79 JNU_ThrowOutOfMemoryError(env, NULL); 80 return; 81 } else if ((*env)->EnsureLocalCapacity(env, (jint)num_packages) == 0) { 82 jboolean failed = JNI_FALSE; 83 int idx; 84 for (idx = 0; idx < num_packages; idx++) { 85 jstring pkg = (*env)->GetObjectArrayElement(env, packages, idx); 86 char* name = GetInternalPackageName(env, pkg, NULL, 0); 87 if (name != NULL) { 88 pkgs[idx] = name; 89 } else { 90 failed = JNI_TRUE; 91 break; 92 } 93 } 94 if (!failed) { 95 JVM_DefineModule(env, module, is_open, version, location, 96 (const char* const*)pkgs, num_packages); 97 } 98 } 99 100 if (num_packages > 0) { 101 int idx; 102 for (idx = 0; idx < num_packages; idx++) { 103 if (pkgs[idx] != NULL) { 104 free(pkgs[idx]); 105 } 106 } 107 free(pkgs); 108 } 109 } 110 111 JNIEXPORT void JNICALL 112 Java_java_lang_Module_addReads0(JNIEnv *env, jclass cls, jobject from, jobject to) 113 { 114 JVM_AddReadsModule(env, from, to); 115 } 116 117 JNIEXPORT void JNICALL 118 Java_java_lang_Module_addExports0(JNIEnv *env, jclass cls, jobject from, 119 jstring pkg, jobject to) 120 { 121 char buf[128]; 122 char* pkg_name; 123 124 if (pkg == NULL) { 125 JNU_ThrowNullPointerException(env, "package is null"); 126 return; 127 } 128 129 pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); 130 if (pkg_name != NULL) { 131 JVM_AddModuleExports(env, from, pkg_name, to); 132 if (pkg_name != buf) { 133 free(pkg_name); 134 } 135 } 136 } 137 138 JNIEXPORT void JNICALL 139 Java_java_lang_Module_addExportsToAll0(JNIEnv *env, jclass cls, jobject from, 140 jstring pkg) 141 { 142 char buf[128]; 143 char* pkg_name; 144 145 if (pkg == NULL) { 146 JNU_ThrowNullPointerException(env, "package is null"); 147 return; 148 } 149 150 pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); 151 if (pkg_name != NULL) { 152 JVM_AddModuleExportsToAll(env, from, pkg_name); 153 if (pkg_name != buf) { 154 free(pkg_name); 155 } 156 } 157 } 158 159 JNIEXPORT void JNICALL 160 Java_java_lang_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls, 161 jobject from, jstring pkg) 162 { 163 char buf[128]; 164 char* pkg_name; 165 166 if (pkg == NULL) { 167 JNU_ThrowNullPointerException(env, "package is null"); 168 return; 169 } 170 171 pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); 172 if (pkg_name != NULL) { 173 JVM_AddModuleExportsToAllUnnamed(env, from, pkg_name); 174 if (pkg_name != buf) { 175 free(pkg_name); 176 } 177 } 178 }