8025922: JNI access to Strings need to check if the value field is non-null

Sat, 05 Oct 2013 15:18:57 +0200

author
sla
date
Sat, 05 Oct 2013 15:18:57 +0200
changeset 5844
f9be370a7d54
parent 5843
763705f0fec3
child 5846
9c63ad02c0a4

8025922: JNI access to Strings need to check if the value field is non-null
Reviewed-by: dholmes, dcubed

src/share/vm/prims/jni.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jniCheck.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/prims/jni.cpp	Fri Oct 04 13:01:07 2013 +0200
     1.2 +++ b/src/share/vm/prims/jni.cpp	Sat Oct 05 15:18:57 2013 +0200
     1.3 @@ -3210,7 +3210,11 @@
     1.4    HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(
     1.5                                      env, string);
     1.6  #endif /* USDT2 */
     1.7 -  jsize ret = java_lang_String::length(JNIHandles::resolve_non_null(string));
     1.8 +  jsize ret = 0;
     1.9 +  oop s = JNIHandles::resolve_non_null(string);
    1.10 +  if (java_lang_String::value(s) != NULL) {
    1.11 +    ret = java_lang_String::length(s);
    1.12 +  }
    1.13  #ifndef USDT2
    1.14    DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);
    1.15  #else /* USDT2 */
    1.16 @@ -3230,20 +3234,23 @@
    1.17   HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
    1.18                                    env, string, (uintptr_t *) isCopy);
    1.19  #endif /* USDT2 */
    1.20 +  jchar* buf = NULL;
    1.21    oop s = JNIHandles::resolve_non_null(string);
    1.22 -  int s_len = java_lang_String::length(s);
    1.23    typeArrayOop s_value = java_lang_String::value(s);
    1.24 -  int s_offset = java_lang_String::offset(s);
    1.25 -  jchar* buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
    1.26 -  /* JNI Specification states return NULL on OOM */
    1.27 -  if (buf != NULL) {
    1.28 -    if (s_len > 0) {
    1.29 -      memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
    1.30 -    }
    1.31 -    buf[s_len] = 0;
    1.32 -    //%note jni_5
    1.33 -    if (isCopy != NULL) {
    1.34 -      *isCopy = JNI_TRUE;
    1.35 +  if (s_value != NULL) {
    1.36 +    int s_len = java_lang_String::length(s);
    1.37 +    int s_offset = java_lang_String::offset(s);
    1.38 +    buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
    1.39 +    /* JNI Specification states return NULL on OOM */
    1.40 +    if (buf != NULL) {
    1.41 +      if (s_len > 0) {
    1.42 +        memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
    1.43 +      }
    1.44 +      buf[s_len] = 0;
    1.45 +      //%note jni_5
    1.46 +      if (isCopy != NULL) {
    1.47 +        *isCopy = JNI_TRUE;
    1.48 +      }
    1.49      }
    1.50    }
    1.51  #ifndef USDT2
    1.52 @@ -3313,7 +3320,11 @@
    1.53   HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(
    1.54                                        env, string);
    1.55  #endif /* USDT2 */
    1.56 -  jsize ret = java_lang_String::utf8_length(JNIHandles::resolve_non_null(string));
    1.57 +  jsize ret = 0;
    1.58 +  oop java_string = JNIHandles::resolve_non_null(string);
    1.59 +  if (java_lang_String::value(java_string) != NULL) {
    1.60 +    ret = java_lang_String::utf8_length(java_string);
    1.61 +  }
    1.62  #ifndef USDT2
    1.63    DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);
    1.64  #else /* USDT2 */
    1.65 @@ -3332,14 +3343,17 @@
    1.66   HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(
    1.67                                       env, string, (uintptr_t *) isCopy);
    1.68  #endif /* USDT2 */
    1.69 +  char* result = NULL;
    1.70    oop java_string = JNIHandles::resolve_non_null(string);
    1.71 -  size_t length = java_lang_String::utf8_length(java_string);
    1.72 -  /* JNI Specification states return NULL on OOM */
    1.73 -  char* result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
    1.74 -  if (result != NULL) {
    1.75 -    java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
    1.76 -    if (isCopy != NULL) {
    1.77 -      *isCopy = JNI_TRUE;
    1.78 +  if (java_lang_String::value(java_string) != NULL) {
    1.79 +    size_t length = java_lang_String::utf8_length(java_string);
    1.80 +    /* JNI Specification states return NULL on OOM */
    1.81 +    result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
    1.82 +    if (result != NULL) {
    1.83 +      java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
    1.84 +      if (isCopy != NULL) {
    1.85 +        *isCopy = JNI_TRUE;
    1.86 +      }
    1.87      }
    1.88    }
    1.89  #ifndef USDT2
     2.1 --- a/src/share/vm/prims/jniCheck.cpp	Fri Oct 04 13:01:07 2013 +0200
     2.2 +++ b/src/share/vm/prims/jniCheck.cpp	Sat Oct 05 15:18:57 2013 +0200
     2.3 @@ -1324,18 +1324,19 @@
     2.4      IN_VM(
     2.5        checkString(thr, str);
     2.6      )
     2.7 +    jchar* newResult = NULL;
     2.8      const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy);
     2.9      assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
    2.10 -
    2.11 -    size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
    2.12 -    jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
    2.13 -    *tagLocation = STRING_TAG;
    2.14 -    jchar* newResult = (jchar*) (tagLocation + 1);
    2.15 -    memcpy(newResult, result, len * sizeof(jchar));
    2.16 -    // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
    2.17 -    // Note that the dtrace arguments for the allocated memory will not match up with this solution.
    2.18 -    FreeHeap((char*)result);
    2.19 -
    2.20 +    if (result != NULL) {
    2.21 +      size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
    2.22 +      jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
    2.23 +      *tagLocation = STRING_TAG;
    2.24 +      newResult = (jchar*) (tagLocation + 1);
    2.25 +      memcpy(newResult, result, len * sizeof(jchar));
    2.26 +      // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes
    2.27 +      // Note that the dtrace arguments for the allocated memory will not match up with this solution.
    2.28 +      FreeHeap((char*)result);
    2.29 +    }
    2.30      functionExit(env);
    2.31      return newResult;
    2.32  JNI_END
    2.33 @@ -1394,18 +1395,19 @@
    2.34      IN_VM(
    2.35        checkString(thr, str);
    2.36      )
    2.37 +    char* newResult = NULL;
    2.38      const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy);
    2.39      assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
    2.40 -
    2.41 -    size_t len = strlen(result) + 1; // + 1 for NULL termination
    2.42 -    jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
    2.43 -    *tagLocation = STRING_UTF_TAG;
    2.44 -    char* newResult = (char*) (tagLocation + 1);
    2.45 -    strcpy(newResult, result);
    2.46 -    // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
    2.47 -    // Note that the dtrace arguments for the allocated memory will not match up with this solution.
    2.48 -    FreeHeap((char*)result, mtInternal);
    2.49 -
    2.50 +    if (result != NULL) {
    2.51 +      size_t len = strlen(result) + 1; // + 1 for NULL termination
    2.52 +      jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
    2.53 +      *tagLocation = STRING_UTF_TAG;
    2.54 +      newResult = (char*) (tagLocation + 1);
    2.55 +      strcpy(newResult, result);
    2.56 +      // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
    2.57 +      // Note that the dtrace arguments for the allocated memory will not match up with this solution.
    2.58 +      FreeHeap((char*)result, mtInternal);
    2.59 +    }
    2.60      functionExit(env);
    2.61      return newResult;
    2.62  JNI_END

mercurial