Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java: UTF-8 related fixes #10652

Merged
merged 2 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 87 additions & 27 deletions swig/include/java/typemaps_java.i
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,45 @@
%include "arrays_java.i";
%include "typemaps.i"


%fragment("SafeNewStringUTF8","header")
%{
static jstring
SafeNewStringUTF8(JNIEnv *jenv, const char* pszInput)
{
jstring ret = 0;
if (pszInput)
{
if( !CPLIsUTF8(pszInput, -1) )
{
CPLError(CE_Warning, CPLE_AppDefined,
"A non-UTF8 string has been detected. Forcing it to ASCII");
char* pszTmp = CPLUTF8ForceToASCII(pszInput, '_');
#ifdef __cplusplus
ret = jenv->NewStringUTF(pszTmp);
#else
ret = (*jenv)->NewStringUTF(jenv, pszTmp);
#endif
CPLFree(pszTmp);
}
else
{
#ifdef __cplusplus
ret = jenv->NewStringUTF(pszInput);
#else
ret = (*jenv)->NewStringUTF(jenv, pszInput);
#endif
}
}
return ret;
}
%}

// Overrides typemap defined in /usr/share/swig4.0/java.swg
%typemap(out, fragment="SafeNewStringUTF8", noblock=1) char * {
$result = SafeNewStringUTF8(jenv, (const char *)$1);
}

%apply (int) {VSI_RETVAL};

%typemap(javabody) SWIGTYPE %{
Expand Down Expand Up @@ -250,7 +289,7 @@
$2 = &pGCPs;
}

%typemap(argout) (int *nGCPs, GDAL_GCP const **pGCPs )
%typemap(argout, fragment="SafeNewStringUTF8") (int *nGCPs, GDAL_GCP const **pGCPs )
{
/* %typemap(argout) (int *nGCPs, GDAL_GCP const **pGCPs ) */
const jclass GCPClass = jenv->FindClass("org/gdal/gdal/GCP");
Expand All @@ -261,8 +300,8 @@

int i;
for (i=0; i<*$1; i++ ) {
jstring stringInfo = jenv->NewStringUTF((*$2)[i].pszInfo);
jstring stringId = jenv->NewStringUTF((*$2)[i].pszId);
jstring stringInfo = SafeNewStringUTF8(jenv, (*$2)[i].pszInfo);
jstring stringId = SafeNewStringUTF8(jenv, (*$2)[i].pszId);
jobject GCPobj = jenv->NewObject(GCPClass, GCPcon,
(*$2)[i].dfGCPX,
(*$2)[i].dfGCPY,
Expand Down Expand Up @@ -441,12 +480,12 @@
* Typemaps for (retStringAndCPLFree*)
***************************************************/

%typemap(out) (retStringAndCPLFree*)
%typemap(out, fragment="SafeNewStringUTF8") (retStringAndCPLFree*)
{
/* %typemap(out) (retStringAndCPLFree*) */
if(result)
{
$result = jenv->NewStringUTF((const char *)result);
$result = SafeNewStringUTF8(jenv, (const char *)result);
CPLFree(result);
}
}
Expand All @@ -459,6 +498,29 @@
return $jnicall;
}

/***************************************************
* Typemaps for (StringAsByteArray*)
***************************************************/

%typemap(out) (StringAsByteArray*)
{
/* %typemap(out) (StringAsByteArray*) */
if(result)
{
const size_t nLen = strlen((const char*)result);
jbyteArray byteArray = jenv->NewByteArray(nLen);
jenv->SetByteArrayRegion(byteArray, (jsize)0, (jsize)nLen, (jbyte*)result);
$result = byteArray;
}
}

%typemap(jni) (StringAsByteArray*) "jbyteArray"
%typemap(jtype) (StringAsByteArray*) "byte[]"
%typemap(jstype) (StringAsByteArray*) "byte[]"
%typemap(javain) (StringAsByteArray*) "$javainput"
%typemap(javaout) (StringAsByteArray*) {
return $jnicall;
}

/***************************************************
* Typemaps for (char **ignorechange)
Expand Down Expand Up @@ -1035,7 +1097,7 @@
}
}

%fragment("GetCSLStringAsHashTable","header")
%fragment("GetCSLStringAsHashTable","header", fragment="SafeNewStringUTF8")
%{
/* Convert a char array to a Hashtable */
static jobject
Expand All @@ -1054,8 +1116,8 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
keyptr = CPLStrdup(*stringarray);
keyptr[pszSep - *stringarray] = '\0';
valptr = pszSep + 1;
jstring name = jenv->NewStringUTF(keyptr);
jstring value = jenv->NewStringUTF(valptr);
jstring name = SafeNewStringUTF8(jenv, keyptr);
jstring value = SafeNewStringUTF8(jenv, valptr);
jenv->CallObjectMethod(jHashtable, put, name, value);
jenv->DeleteLocalRef(name);
jenv->DeleteLocalRef(value);
Expand Down Expand Up @@ -1151,7 +1213,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
CSLDestroy( $1 );
}

%typemap(out) char **options
%typemap(out, fragment="SafeNewStringUTF8") char **options
{
/* %typemap(out) char **options */
char **stringarray = $1;
Expand All @@ -1162,8 +1224,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$result = jenv->NewObject(vector, constructor);
if ( stringarray != NULL ) {
while(*stringarray != NULL) {
/*printf("working on string %s\n", *stringarray);*/
jstring value = (jstring)jenv->NewStringUTF(*stringarray);
jstring value = SafeNewStringUTF8(jenv, *stringarray);
jenv->CallBooleanMethod($result, add, value);
jenv->DeleteLocalRef(value);
stringarray++;
Expand All @@ -1183,7 +1244,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
* Typemaps for retAsStringArrayNoFree
***************************************************/

%typemap(out) char **retAsStringArrayNoFree
%typemap(out,fragment="SafeNewStringUTF8") char **retAsStringArrayNoFree
{
/* %typemap(out) char **retAsStringArrayNoFree */
char **stringarray = result;
Expand All @@ -1196,7 +1257,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* exception checking omitted */

for (i=0; i<len; i++) {
temp_string = jenv->NewStringUTF(*stringarray++);
temp_string = SafeNewStringUTF8(jenv, *stringarray++);
jenv->SetObjectArrayElement(jresult, i, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand All @@ -1214,7 +1275,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
* Typemaps for retAsStringArrayNoFree
***************************************************/

%typemap(out) char **retAsStringArrayAndFree
%typemap(out, fragment="SafeNewStringUTF8") char **retAsStringArrayAndFree
{
/* %typemap(out) char **retAsStringArrayAndFree */
char **stringarray = result;
Expand All @@ -1227,7 +1288,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* exception checking omitted */

for (i=0; i<len; i++) {
temp_string = jenv->NewStringUTF(*stringarray++);
temp_string = SafeNewStringUTF8(jenv, *stringarray++);
jenv->SetObjectArrayElement(jresult, i, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand Down Expand Up @@ -1261,10 +1322,10 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$1 = &ret;
}

%typemap(argout) char **OUTPUT
%typemap(argout, fragment="SafeNewStringUTF8") char **OUTPUT
{
/* %typemap(argout) char **OUTPUT */
jstring temp_string = jenv->NewStringUTF(ret$argnum);
jstring temp_string = SafeNewStringUTF8(jenv, ret$argnum);
jenv->SetObjectArrayElement($input, 0, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand All @@ -1285,7 +1346,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* Almost same as %typemap(out) char **options */
/* but we CSLDestroy the char** pointer at the end */

%typemap(out) char **CSL
%typemap(out, fragment="SafeNewStringUTF8") char **CSL
{
/* %typemap(out) char **CSL */
char **stringarray = $1;
Expand All @@ -1296,8 +1357,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$result = jenv->NewObject(vector, constructor);
if ( stringarray != NULL ) {
while(*stringarray != NULL) {
/*printf("working on string %s\n", *stringarray);*/
jstring value = (jstring)jenv->NewStringUTF(*stringarray);
jstring value = SafeNewStringUTF8(jenv, *stringarray);
jenv->CallBooleanMethod($result, add, value);
jenv->DeleteLocalRef(value);
stringarray++;
Expand All @@ -1324,13 +1384,13 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
$1 = &argout;
}

%typemap(argout) (char **argout)
%typemap(argout, fragment="SafeNewStringUTF8") (char **argout)
{
/* %typemap(argout) (char **argout) */
jstring temp_string;

if($input != NULL && (int)jenv->GetArrayLength($input) >= 1) {
temp_string = jenv->NewStringUTF(argout$argnum);
temp_string = SafeNewStringUTF8(jenv, argout$argnum);
jenv->SetObjectArrayElement($input, 0, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand Down Expand Up @@ -1497,7 +1557,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {

/* This allows a C function to return a char ** as a Java String array */

%typemap(out) char ** {
%typemap(out, fragment="SafeNewStringUTF8") char ** {
/* %typemap(out) char ** */
int i;
int len=0;
Expand All @@ -1509,7 +1569,7 @@ GetCSLStringAsHashTable(JNIEnv *jenv, char **stringarray, bool bFreeCSL ) {
/* exception checking omitted */

for (i=0; i<len; i++) {
temp_string = jenv->NewStringUTF(*result++);
temp_string = SafeNewStringUTF8(jenv, *result++);
jenv->SetObjectArrayElement(jresult, i, temp_string);
jenv->DeleteLocalRef(temp_string);
}
Expand Down Expand Up @@ -2509,7 +2569,7 @@ DEFINE_BOOLEAN_FUNC_ARRAY_IN(double, jdouble, GetDoubleArrayElements, ReleaseDou
CPLFree( $1 );
}

%typemap(out) OGRCodedValue*
%typemap(out, fragment="SafeNewStringUTF8") OGRCodedValue*
{
/* %typemap(out) OGRCodedValue* */
/* Convert a OGRCodedValue* to a HashMap */
Expand All @@ -2525,10 +2585,10 @@ DEFINE_BOOLEAN_FUNC_ARRAY_IN(double, jdouble, GetDoubleArrayElements, ReleaseDou
$result = jenv->NewObject(hashMapClass, constructor);
for( int i = 0; ($1)[i].pszCode != NULL; i++ )
{
jstring name = jenv->NewStringUTF(($1)[i].pszCode);
jstring name = SafeNewStringUTF8(jenv, ($1)[i].pszCode);
if( ($1)[i].pszValue )
{
jstring value = jenv->NewStringUTF(($1)[i].pszValue);
jstring value = SafeNewStringUTF8(jenv, ($1)[i].pszValue);
jenv->CallObjectMethod($result, put, name, value);
jenv->DeleteLocalRef(value);
}
Expand Down
Loading
Loading