8025922: JNI access to Strings need to check if the value field is non-null
authorsla
Sat, 05 Oct 2013 15:18:57 +0200
changeset 20387 df9f9f220120
parent 20386 d0c34895af33
child 20389 a01c654bf130
8025922: JNI access to Strings need to check if the value field is non-null Reviewed-by: dholmes, dcubed
hotspot/src/share/vm/prims/jni.cpp
hotspot/src/share/vm/prims/jniCheck.cpp
--- a/hotspot/src/share/vm/prims/jni.cpp	Fri Oct 04 13:01:07 2013 +0200
+++ b/hotspot/src/share/vm/prims/jni.cpp	Sat Oct 05 15:18:57 2013 +0200
@@ -3210,7 +3210,11 @@
   HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(
                                     env, string);
 #endif /* USDT2 */
-  jsize ret = java_lang_String::length(JNIHandles::resolve_non_null(string));
+  jsize ret = 0;
+  oop s = JNIHandles::resolve_non_null(string);
+  if (java_lang_String::value(s) != NULL) {
+    ret = java_lang_String::length(s);
+  }
 #ifndef USDT2
   DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);
 #else /* USDT2 */
@@ -3230,20 +3234,23 @@
  HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
                                   env, string, (uintptr_t *) isCopy);
 #endif /* USDT2 */
+  jchar* buf = NULL;
   oop s = JNIHandles::resolve_non_null(string);
-  int s_len = java_lang_String::length(s);
   typeArrayOop s_value = java_lang_String::value(s);
-  int s_offset = java_lang_String::offset(s);
-  jchar* buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
-  /* JNI Specification states return NULL on OOM */
-  if (buf != NULL) {
-    if (s_len > 0) {
-      memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
-    }
-    buf[s_len] = 0;
-    //%note jni_5
-    if (isCopy != NULL) {
-      *isCopy = JNI_TRUE;
+  if (s_value != NULL) {
+    int s_len = java_lang_String::length(s);
+    int s_offset = java_lang_String::offset(s);
+    buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
+    /* JNI Specification states return NULL on OOM */
+    if (buf != NULL) {
+      if (s_len > 0) {
+        memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
+      }
+      buf[s_len] = 0;
+      //%note jni_5
+      if (isCopy != NULL) {
+        *isCopy = JNI_TRUE;
+      }
     }
   }
 #ifndef USDT2
@@ -3313,7 +3320,11 @@
  HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(
                                       env, string);
 #endif /* USDT2 */
-  jsize ret = java_lang_String::utf8_length(JNIHandles::resolve_non_null(string));
+  jsize ret = 0;
+  oop java_string = JNIHandles::resolve_non_null(string);
+  if (java_lang_String::value(java_string) != NULL) {
+    ret = java_lang_String::utf8_length(java_string);
+  }
 #ifndef USDT2
   DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);
 #else /* USDT2 */
@@ -3332,14 +3343,17 @@
  HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(
                                      env, string, (uintptr_t *) isCopy);
 #endif /* USDT2 */
+  char* result = NULL;
   oop java_string = JNIHandles::resolve_non_null(string);
-  size_t length = java_lang_String::utf8_length(java_string);
-  /* JNI Specification states return NULL on OOM */
-  char* result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
-  if (result != NULL) {
-    java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
-    if (isCopy != NULL) {
-      *isCopy = JNI_TRUE;
+  if (java_lang_String::value(java_string) != NULL) {
+    size_t length = java_lang_String::utf8_length(java_string);
+    /* JNI Specification states return NULL on OOM */
+    result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
+    if (result != NULL) {
+      java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
+      if (isCopy != NULL) {
+        *isCopy = JNI_TRUE;
+      }
     }
   }
 #ifndef USDT2
--- a/hotspot/src/share/vm/prims/jniCheck.cpp	Fri Oct 04 13:01:07 2013 +0200
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp	Sat Oct 05 15:18:57 2013 +0200
@@ -1324,18 +1324,19 @@
     IN_VM(
       checkString(thr, str);
     )
+    jchar* newResult = NULL;
     const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
     assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
-
-    size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
-    jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
-    *tagLocation = STRING_TAG;
-    jchar* newResult = (jchar*) (tagLocation + 1);
-    memcpy(newResult, result, len * sizeof(jchar));
-    // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
-    // Note that the dtrace arguments for the allocated memory will not match up with this solution.
-    FreeHeap((char*)result);
-
+    if (result != NULL) {
+      size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
+      jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
+      *tagLocation = STRING_TAG;
+      newResult = (jchar*) (tagLocation + 1);
+      memcpy(newResult, result, len * sizeof(jchar));
+      // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
+      // Note that the dtrace arguments for the allocated memory will not match up with this solution.
+      FreeHeap((char*)result);
+    }
     functionExit(env);
     return newResult;
 JNI_END
@@ -1394,18 +1395,19 @@
     IN_VM(
       checkString(thr, str);
     )
+    char* newResult = NULL;
     const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
     assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
-
-    size_t len = strlen(result) + 1; // + 1 for NULL termination
-    jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
-    *tagLocation = STRING_UTF_TAG;
-    char* newResult = (char*) (tagLocation + 1);
-    strcpy(newResult, result);
-    // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
-    // Note that the dtrace arguments for the allocated memory will not match up with this solution.
-    FreeHeap((char*)result, mtInternal);
-
+    if (result != NULL) {
+      size_t len = strlen(result) + 1; // + 1 for NULL termination
+      jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
+      *tagLocation = STRING_UTF_TAG;
+      newResult = (char*) (tagLocation + 1);
+      strcpy(newResult, result);
+      // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
+      // Note that the dtrace arguments for the allocated memory will not match up with this solution.
+      FreeHeap((char*)result, mtInternal);
+    }
     functionExit(env);
     return newResult;
 JNI_END