--- old/src/java.base/share/native/libjava/Module.c 2017-02-07 13:13:51.003451314 +0000 +++ new/src/java.base/share/native/libjava/Module.c 2017-02-07 13:13:50.836439845 +0000 @@ -22,18 +22,88 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +#include +#include #include "jni.h" +#include "jni_util.h" #include "jvm.h" #include "java_lang_reflect_Module.h" +/* + * Gets the UTF-8 chars for the string and translates '.' to '/'. Does no + * further validation, assumption being that both calling code in + * java.lang.reflect.Module and VM will do deeper validation. + */ +static char* +GetInternalPackageName(JNIEnv *env, jstring pkg, char* buf, jsize buf_size) +{ + jsize len; + jsize unicode_len; + char* p; + char* utf_str; + + len = (*env)->GetStringUTFLength(env, pkg); + unicode_len = (*env)->GetStringLength(env, pkg); + if (len >= buf_size) { + utf_str = malloc(len + 1); + if (utf_str == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return NULL; + } + } else { + utf_str = buf; + } + (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, utf_str); + + p = utf_str; + while (*p != '\0') { + if (*p == '.') { + *p = '/'; + } + p++; + } + return utf_str; +} + JNIEXPORT void JNICALL Java_java_lang_reflect_Module_defineModule0(JNIEnv *env, jclass cls, jobject module, jboolean is_open, jstring version, jstring location, jobjectArray packages) { - JVM_DefineModule(env, module, is_open, version, location, packages); + char** pkgs = NULL; + jsize idx; + jsize num_packages = (*env)->GetArrayLength(env, packages); + + if (num_packages != 0 && (pkgs = calloc(num_packages, sizeof(char*))) == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return; + } else { + int valid = 1; + for (idx = 0; idx < num_packages; idx++) { + jstring pkg = (*env)->GetObjectArrayElement(env, packages, idx); + pkgs[idx] = GetInternalPackageName(env, pkg, NULL, 0); + if (pkgs[idx] == NULL) { + valid = 0; + break; + } + } + + if (valid != 0) { + JVM_DefineModule(env, module, is_open, version, location, + (const char* const*)pkgs, num_packages); + } + } + + if (num_packages > 0) { + for (idx = 0; idx < num_packages; idx++) { + if (pkgs[idx] != NULL) { + free(pkgs[idx]); + } + } + free(pkgs); + } } JNIEXPORT void JNICALL @@ -46,25 +116,81 @@ Java_java_lang_reflect_Module_addExports0(JNIEnv *env, jclass cls, jobject from, jstring pkg, jobject to) { - JVM_AddModuleExports(env, from, pkg, to); + char buf[128]; + char* pkg_name; + + if (pkg == NULL) { + JNU_ThrowNullPointerException(env, "package is null"); + return; + } + + pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); + if (pkg_name != NULL) { + JVM_AddModuleExports(env, from, pkg_name, to); + if (pkg_name != buf) { + free(pkg_name); + } + } } JNIEXPORT void JNICALL Java_java_lang_reflect_Module_addExportsToAll0(JNIEnv *env, jclass cls, jobject from, jstring pkg) { - JVM_AddModuleExportsToAll(env, from, pkg); + char buf[128]; + char* pkg_name; + + if (pkg == NULL) { + JNU_ThrowNullPointerException(env, "package is null"); + return; + } + + pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); + if (pkg_name != NULL) { + JVM_AddModuleExportsToAll(env, from, pkg_name); + if (pkg_name != buf) { + free(pkg_name); + } + } } JNIEXPORT void JNICALL Java_java_lang_reflect_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls, jobject from, jstring pkg) { - JVM_AddModuleExportsToAllUnnamed(env, from, pkg); + char buf[128]; + char* pkg_name; + + if (pkg == NULL) { + JNU_ThrowNullPointerException(env, "package is null"); + return; + } + + pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); + if (pkg_name != NULL) { + JVM_AddModuleExportsToAllUnnamed(env, from, pkg_name); + if (pkg_name != buf) { + free(pkg_name); + } + } } JNIEXPORT void JNICALL Java_java_lang_reflect_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg) { - JVM_AddModulePackage(env, m, pkg); + char buf[128]; + char* pkg_name; + + if (pkg == NULL) { + JNU_ThrowNullPointerException(env, "package is null"); + return; + } + + pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf)); + if (pkg_name != NULL) { + JVM_AddModulePackage(env, m, pkg_name); + if (pkg_name != buf) { + free(pkg_name); + } + } }