@@ -577,18 +577,33 @@ dispatch(JNIEnv *env, void* func, jint flags, jobjectArray arr,
577
577
}
578
578
}
579
579
580
+ /** Copy characters from the Java character array into native memory. */
580
581
static void
581
582
getChars (JNIEnv * env , wchar_t * dst , jcharArray chars , jint off , jint len ) {
582
583
PSTART ();
584
+
583
585
if (sizeof (jchar ) == sizeof (wchar_t )) {
584
586
(* env )-> GetCharArrayRegion (env , chars , off , len , (jchar * )dst );
585
587
}
586
588
else {
587
- int i ;
588
- jchar * buf = (jchar * )alloca (len * sizeof (jchar ));
589
- (* env )-> GetCharArrayRegion (env , chars , off , len , buf );
590
- for (i = 0 ;i < len ;i ++ ) {
591
- dst [i ] = (wchar_t )buf [i ];
589
+ jchar * buf ;
590
+ int count = len > 1000 ? 1000 : len ;
591
+ buf = (jchar * )alloca (count * sizeof (jchar ));
592
+ if (!buf ) {
593
+ throwByName (env , EOutOfMemory , "Can't read characters" );
594
+ }
595
+ else {
596
+ while (len > 0 ) {
597
+ int i ;
598
+ (* env )-> GetCharArrayRegion (env , chars , off , count , buf );
599
+ for (i = 0 ;i < count ;i ++ ) {
600
+ dst [i ] = (wchar_t )buf [i ];
601
+ }
602
+ dst += count ;
603
+ off += count ;
604
+ len -= count ;
605
+ if (count > len ) count = len ;
606
+ }
592
607
}
593
608
}
594
609
PEND ();
@@ -597,16 +612,31 @@ getChars(JNIEnv* env, wchar_t* dst, jcharArray chars, jint off, jint len) {
597
612
static void
598
613
setChars (JNIEnv * env , wchar_t * src , jcharArray chars , jint off , jint len ) {
599
614
jchar * buf = (jchar * )src ;
615
+ int malloced = 0 ;
600
616
PSTART ();
601
617
602
- if (sizeof (jchar ) != sizeof (wchar_t )) {
603
- int i ;
604
- buf = (jchar * )alloca (len * sizeof (jchar ));
605
- for (i = 0 ;i < len ;i ++ ) {
606
- buf [i ] = (jchar )src [i ];
618
+ if (sizeof (jchar ) == sizeof (wchar_t )) {
619
+ (* env )-> SetCharArrayRegion (env , chars , off , len , buf );
620
+ }
621
+ else {
622
+ int count = len > 1000 ? 1000 : len ;
623
+ buf = (jchar * )alloca (count * sizeof (jchar ));
624
+ if (!buf ) {
625
+ throwByName (env , EOutOfMemory , "Can't write characters" );
626
+ }
627
+ else {
628
+ while (len > 0 ) {
629
+ int i ;
630
+ for (i = 0 ;i < count ;i ++ ) {
631
+ buf [i ] = (jchar )src [off + i ];
632
+ }
633
+ (* env )-> SetCharArrayRegion (env , chars , off , count , buf );
634
+ off += count ;
635
+ len -= count ;
636
+ if (count > len ) count = len ;
637
+ }
607
638
}
608
639
}
609
- (* env )-> SetCharArrayRegion (env , chars , off , len , buf );
610
640
PEND ();
611
641
}
612
642
@@ -690,7 +720,13 @@ newWideCString(JNIEnv *env, jstring str)
690
720
}
691
721
// TODO: ensure proper encoding conversion from jchar to native wchar_t
692
722
getChars (env , result , chars , 0 , len );
693
- result [len ] = 0 ; /* NUL-terminate */
723
+ if ((* env )-> ExceptionCheck (env )) {
724
+ free ((void * )result );
725
+ result = NULL ;
726
+ }
727
+ else {
728
+ result [len ] = 0 ; /* NUL-terminate */
729
+ }
694
730
}
695
731
(* env )-> DeleteLocalRef (env , chars );
696
732
return result ;
@@ -722,14 +758,22 @@ newJavaString(JNIEnv *env, const char *ptr, jboolean wide)
722
758
if (ptr ) {
723
759
if (wide ) {
724
760
// TODO: proper conversion from native wchar_t to jchar, if any
725
- int len = (int )wcslen ((const wchar_t * )ptr );
761
+ jsize len = (int )wcslen ((const wchar_t * )ptr );
726
762
if (sizeof (jchar ) != sizeof (wchar_t )) {
727
- jchar * buf = (jchar * )alloca (len * sizeof (jchar ));
728
- int i ;
729
- for (i = 0 ;i < len ;i ++ ) {
730
- buf [i ] = * ((const wchar_t * )ptr + i );
763
+ // NOTE: while alloca may succeed here, writing to the stack
764
+ // memory may fail with really large buffers
765
+ jchar * buf = (jchar * )malloc (len * sizeof (jchar ));
766
+ if (!buf ) {
767
+ throwByName (env , EOutOfMemory , "Can't allocate space for conversion to Java String" );
768
+ }
769
+ else {
770
+ int i ;
771
+ for (i = 0 ;i < len ;i ++ ) {
772
+ buf [i ] = * ((const wchar_t * )ptr + i );
773
+ }
774
+ result = (* env )-> NewString (env , buf , len );
775
+ free ((void * )buf );
731
776
}
732
- result = (* env )-> NewString (env , buf , len );
733
777
}
734
778
else {
735
779
result = (* env )-> NewString (env , (const jchar * )ptr , len );
@@ -1166,8 +1210,9 @@ get_system_property(JNIEnv* env, const char* name, jboolean wide) {
1166
1210
jstring value = (* env )-> CallStaticObjectMethod (env , classSystem ,
1167
1211
mid , propname );
1168
1212
if (value ) {
1169
- if (wide )
1213
+ if (wide ) {
1170
1214
return newWideCString (env , value );
1215
+ }
1171
1216
return newCStringUTF8 (env , value );
1172
1217
}
1173
1218
}
@@ -2751,7 +2796,7 @@ Java_com_sun_jna_Native_getWindowHandle0(JNIEnv *env, jclass UNUSED(classp), job
2751
2796
#else
2752
2797
swprintf (path , L"%s%s" , prop , suffix );
2753
2798
#endif
2754
- free (prop );
2799
+ free (( void * ) prop );
2755
2800
}
2756
2801
#undef JAWT_NAME
2757
2802
#define JAWT_NAME path
0 commit comments