Skip to content

Commit

Permalink
Java bindings: make sure a valid UTF-8 string is passed to NewStringU…
Browse files Browse the repository at this point in the history
…TF()
  • Loading branch information
rouault committed Aug 26, 2024
1 parent f7447c6 commit f1e35a9
Showing 1 changed file with 64 additions and 27 deletions.
91 changes: 64 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 Down Expand Up @@ -1035,7 +1074,7 @@
}
}

%fragment("GetCSLStringAsHashTable","header")
%fragment("GetCSLStringAsHashTable","header", fragment="SafeNewStringUTF8")
%{
/* Convert a char array to a Hashtable */
static jobject
Expand All @@ -1054,8 +1093,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 +1190,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 +1201,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 +1221,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 +1234,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 +1252,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 +1265,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 +1299,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 +1323,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 +1334,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 +1361,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 +1534,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 +1546,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 +2546,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 +2562,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

0 comments on commit f1e35a9

Please sign in to comment.