< prev index next >

src/java.base/share/native/libjava/jni_util.c

Print this page
rev 12062 : 8081674: EmptyStackException at startup if running with extended or unsupported charset
   1 /*
   2  * Copyright (c) 1997, 2014, 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


 692     CHECK_NULL(String_getBytes_ID);
 693     String_init_ID = (*env)->GetMethodID(env, strClazz,
 694                                          "<init>", "([BLjava/lang/String;)V");
 695 }
 696 
 697 static jboolean isJNUEncodingSupported = JNI_FALSE;
 698 static jboolean jnuEncodingSupported(JNIEnv *env) {
 699     jboolean exe;
 700     if (isJNUEncodingSupported == JNI_TRUE) {
 701         return JNI_TRUE;
 702     }
 703     isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
 704                                     env, &exe,
 705                                     "java/nio/charset/Charset",
 706                                     "isSupported",
 707                                     "(Ljava/lang/String;)Z",
 708                                     jnuEncoding).z;
 709     return isJNUEncodingSupported;
 710 }
 711 









 712 
 713 JNIEXPORT jstring
 714 NewStringPlatform(JNIEnv *env, const char *str)
 715 {
 716     return JNU_NewStringPlatform(env, str);
 717 }
 718 
 719 JNIEXPORT jstring JNICALL
 720 JNU_NewStringPlatform(JNIEnv *env, const char *str)
 721 {
 722     jstring result = NULL;
 723     jbyteArray hab = 0;
 724     int len;
 725 
 726     if (fastEncoding == NO_ENCODING_YET) {
 727         initializeEncoding(env);
 728         JNU_CHECK_EXCEPTION_RETURN(env, NULL);
 729     }
 730 
 731     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
 732         return newString8859_1(env, str);
 733     if (fastEncoding == FAST_646_US)
 734         return newString646_US(env, str);
 735     if (fastEncoding == FAST_CP1252)
 736         return newStringCp1252(env, str);
 737 
 738     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
 739         return NULL;
 740 
 741     len = (int)strlen(str);
 742     hab = (*env)->NewByteArray(env, len);
 743     if (hab != 0) {
 744         jclass strClazz = JNU_ClassString(env);
 745         CHECK_NULL_RETURN(strClazz, 0);
 746         (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
 747         if (jnuEncodingSupported(env)) {
 748             result = (*env)->NewObject(env, strClazz,
 749                                        String_init_ID, hab, jnuEncoding);
 750         } else {

 751             /*If the encoding specified in sun.jnu.encoding is not endorsed
 752               by "Charset.isSupported" we have to fall back to use String(byte[])
 753               explicitly here without specifying the encoding name, in which the
 754               StringCoding class will pickup the iso-8859-1 as the fallback
 755               converter for us.
 756              */
 757             jmethodID mid = (*env)->GetMethodID(env, strClazz,
 758                                                 "<init>", "([B)V");
 759             if (mid != NULL) {
 760                 result = (*env)->NewObject(env, strClazz, mid, hab);
 761             }
 762         }
 763         (*env)->DeleteLocalRef(env, hab);
 764         return result;
 765     }
 766     return NULL;
 767 }
 768 
 769 JNIEXPORT const char *
 770 GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)


 782         *isCopy = JNI_TRUE;
 783 
 784     if (fastEncoding == NO_ENCODING_YET) {
 785         initializeEncoding(env);
 786         JNU_CHECK_EXCEPTION_RETURN(env, 0);
 787     }
 788 
 789     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
 790         return getString8859_1Chars(env, jstr);
 791     if (fastEncoding == FAST_646_US)
 792         return getString646_USChars(env, jstr);
 793     if (fastEncoding == FAST_CP1252)
 794         return getStringCp1252Chars(env, jstr);
 795 
 796     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
 797         return 0;
 798 
 799     if (jnuEncodingSupported(env)) {
 800         hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
 801     } else {

 802         jmethodID mid;
 803         jclass strClazz = JNU_ClassString(env);
 804         CHECK_NULL_RETURN(strClazz, 0);
 805         mid = (*env)->GetMethodID(env, strClazz,
 806                                        "getBytes", "()[B");
 807         if (mid != NULL) {
 808             hab = (*env)->CallObjectMethod(env, jstr, mid);
 809         }
 810     }
 811 
 812     if (!(*env)->ExceptionCheck(env)) {
 813         jint len = (*env)->GetArrayLength(env, hab);
 814         result = MALLOC_MIN4(len);
 815         if (result == 0) {
 816             JNU_ThrowOutOfMemoryError(env, 0);
 817             (*env)->DeleteLocalRef(env, hab);
 818             return 0;
 819         }
 820         (*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
 821         result[len] = 0; /* NULL-terminate */


   1 /*
   2  * Copyright (c) 1997, 2015, 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


 692     CHECK_NULL(String_getBytes_ID);
 693     String_init_ID = (*env)->GetMethodID(env, strClazz,
 694                                          "<init>", "([BLjava/lang/String;)V");
 695 }
 696 
 697 static jboolean isJNUEncodingSupported = JNI_FALSE;
 698 static jboolean jnuEncodingSupported(JNIEnv *env) {
 699     jboolean exe;
 700     if (isJNUEncodingSupported == JNI_TRUE) {
 701         return JNI_TRUE;
 702     }
 703     isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
 704                                     env, &exe,
 705                                     "java/nio/charset/Charset",
 706                                     "isSupported",
 707                                     "(Ljava/lang/String;)Z",
 708                                     jnuEncoding).z;
 709     return isJNUEncodingSupported;
 710 }
 711 
 712 static jboolean _warnUnsupportedEncoding = JNI_TRUE;
 713 static void warnUnsupportedEncoding(JNIEnv *env) {
 714     if (_warnUnsupportedEncoding) {
 715         _warnUnsupportedEncoding = JNI_FALSE;
 716         jio_fprintf(stderr,
 717                     "Warning: encoding '%s' not supported - falling back to default encoding.\n",
 718                     (*env)->GetStringUTFChars(env, jnuEncoding, 0));
 719     }
 720 }
 721 
 722 JNIEXPORT jstring
 723 NewStringPlatform(JNIEnv *env, const char *str)
 724 {
 725     return JNU_NewStringPlatform(env, str);
 726 }
 727 
 728 JNIEXPORT jstring JNICALL
 729 JNU_NewStringPlatform(JNIEnv *env, const char *str)
 730 {
 731     jstring result = NULL;
 732     jbyteArray hab = 0;
 733     int len;
 734 
 735     if (fastEncoding == NO_ENCODING_YET) {
 736         initializeEncoding(env);
 737         JNU_CHECK_EXCEPTION_RETURN(env, NULL);
 738     }
 739 
 740     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
 741         return newString8859_1(env, str);
 742     if (fastEncoding == FAST_646_US)
 743         return newString646_US(env, str);
 744     if (fastEncoding == FAST_CP1252)
 745         return newStringCp1252(env, str);
 746 
 747     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
 748         return NULL;
 749 
 750     len = (int)strlen(str);
 751     hab = (*env)->NewByteArray(env, len);
 752     if (hab != 0) {
 753         jclass strClazz = JNU_ClassString(env);
 754         CHECK_NULL_RETURN(strClazz, 0);
 755         (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
 756         if (jnuEncodingSupported(env)) {
 757             result = (*env)->NewObject(env, strClazz,
 758                                        String_init_ID, hab, jnuEncoding);
 759         } else {
 760             warnUnsupportedEncoding(env);
 761             /*If the encoding specified in sun.jnu.encoding is not endorsed
 762               by "Charset.isSupported" we have to fall back to use String(byte[])
 763               explicitly here without specifying the encoding name, in which the
 764               StringCoding class will pickup the iso-8859-1 as the fallback
 765               converter for us.
 766              */
 767             jmethodID mid = (*env)->GetMethodID(env, strClazz,
 768                                                 "<init>", "([B)V");
 769             if (mid != NULL) {
 770                 result = (*env)->NewObject(env, strClazz, mid, hab);
 771             }
 772         }
 773         (*env)->DeleteLocalRef(env, hab);
 774         return result;
 775     }
 776     return NULL;
 777 }
 778 
 779 JNIEXPORT const char *
 780 GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)


 792         *isCopy = JNI_TRUE;
 793 
 794     if (fastEncoding == NO_ENCODING_YET) {
 795         initializeEncoding(env);
 796         JNU_CHECK_EXCEPTION_RETURN(env, 0);
 797     }
 798 
 799     if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
 800         return getString8859_1Chars(env, jstr);
 801     if (fastEncoding == FAST_646_US)
 802         return getString646_USChars(env, jstr);
 803     if (fastEncoding == FAST_CP1252)
 804         return getStringCp1252Chars(env, jstr);
 805 
 806     if ((*env)->EnsureLocalCapacity(env, 2) < 0)
 807         return 0;
 808 
 809     if (jnuEncodingSupported(env)) {
 810         hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
 811     } else {
 812         warnUnsupportedEncoding(env);
 813         jmethodID mid;
 814         jclass strClazz = JNU_ClassString(env);
 815         CHECK_NULL_RETURN(strClazz, 0);
 816         mid = (*env)->GetMethodID(env, strClazz,
 817                                        "getBytes", "()[B");
 818         if (mid != NULL) {
 819             hab = (*env)->CallObjectMethod(env, jstr, mid);
 820         }
 821     }
 822 
 823     if (!(*env)->ExceptionCheck(env)) {
 824         jint len = (*env)->GetArrayLength(env, hab);
 825         result = MALLOC_MIN4(len);
 826         if (result == 0) {
 827             JNU_ThrowOutOfMemoryError(env, 0);
 828             (*env)->DeleteLocalRef(env, hab);
 829             return 0;
 830         }
 831         (*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
 832         result[len] = 0; /* NULL-terminate */


< prev index next >