Sat, 05 Oct 2013 15:18:57 +0200
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