Skip to content

Commit

Permalink
Fix jpy vararg leak
Browse files Browse the repository at this point in the history
Co-authored-by: Charles P. Wright <charleswright@illumon.com>
  • Loading branch information
devinrsmith and cpwright committed Apr 25, 2022
1 parent 9c2b9bd commit 7959d6f
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 104 deletions.
13 changes: 5 additions & 8 deletions src/main/c/jni/org_jpy_PyLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1858,22 +1858,19 @@ JNIEXPORT jobjectArray JNICALL Java_org_jpy_PyLib_getObjectArrayValue
for (i = 0; i < length; i++) {
pyItem = PySequence_GetItem(pyObject, i);
if (pyItem == NULL) {
(*jenv)->DeleteLocalRef(jenv, jObject);
jObject = NULL;
JPy_DELETE_LOCAL_REF(jObject);
goto error;
}
if (JPy_AsJObject(jenv, pyItem, &jItem, JNI_FALSE) < 0) {
(*jenv)->DeleteLocalRef(jenv, jObject);
jObject = NULL;
JPy_DELETE_LOCAL_REF(jObject);
JPy_DIAG_PRINT(JPy_DIAG_F_ALL, "Java_org_jpy_PyLib_getObjectArrayValue: error: failed to convert Python item to Java Object\n");
PyLib_HandlePythonException(jenv);
goto error;
}
JPy_XDECREF(pyItem);
(*jenv)->SetObjectArrayElement(jenv, jObject, i, jItem);
if ((*jenv)->ExceptionCheck(jenv)) {
(*jenv)->DeleteLocalRef(jenv, jObject);
jObject = NULL;
JPy_DELETE_LOCAL_REF(jObject);
goto error;
}
}
Expand Down Expand Up @@ -2337,9 +2334,9 @@ PyObject* PyLib_CallAndReturnObject(JNIEnv *jenv, PyObject* pyObject, jboolean i
}
pyArg = PyLib_FromJObjectForTuple(jenv, jArg, jParamClass, nameChars, i);
if (jParamClass != NULL) {
(*jenv)->DeleteLocalRef(jenv, jParamClass);
jParamClass = NULL;
JPy_DELETE_LOCAL_REF(jParamClass);
}
JPy_DELETE_LOCAL_REF(jArg);
if (pyArg == NULL) {
JPy_DIAG_PRINT(JPy_DIAG_F_ALL, "PyLib_CallAndReturnObject: error: callable '%s': argument %d: failed to convert Java into Python object\n", nameChars, i);
PyLib_HandlePythonException(jenv);
Expand Down
4 changes: 2 additions & 2 deletions src/main/c/jpy_conv.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ char* JPy_GetTypeName(JNIEnv* jenv, jclass classRef)
typeNameCopy = JPy_CopyUTFString(jTypeNameChars);
(*jenv)->ReleaseStringUTFChars(jenv, jTypeName, jTypeNameChars);
}
(*jenv)->DeleteLocalRef(jenv, jTypeName);
JPy_DELETE_LOCAL_REF(jTypeName);
return typeNameCopy;
}

Expand All @@ -190,7 +190,7 @@ PyObject* JPy_FromTypeName(JNIEnv* jenv, jclass classRef)
pyTypeName = Py_BuildValue("s", jTypeNameChars);
(*jenv)->ReleaseStringUTFChars(jenv, jTypeName, jTypeNameChars);
}
(*jenv)->DeleteLocalRef(jenv, jTypeName);
JPy_DELETE_LOCAL_REF(jTypeName);
return pyTypeName;
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/c/jpy_jmethod.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,12 +307,12 @@ PyObject* JMethod_InvokeMethod(JNIEnv* jenv, JPy_JMethod* method, PyObject* pyAr
jstring v = (*jenv)->CallStaticObjectMethodA(jenv, classRef, method->mid, jArgs);
JPy_ON_JAVA_EXCEPTION_GOTO(error);
returnValue = JPy_FromJString(jenv, v);
(*jenv)->DeleteLocalRef(jenv, v);
JPy_DELETE_LOCAL_REF(v);
} else {
jobject v = (*jenv)->CallStaticObjectMethodA(jenv, classRef, method->mid, jArgs);
JPy_ON_JAVA_EXCEPTION_GOTO(error);
returnValue = JMethod_FromJObject(jenv, method, pyArgs, jArgs, 0, returnType, v);
(*jenv)->DeleteLocalRef(jenv, v);
JPy_DELETE_LOCAL_REF(v);
}

} else {
Expand Down Expand Up @@ -365,12 +365,12 @@ PyObject* JMethod_InvokeMethod(JNIEnv* jenv, JPy_JMethod* method, PyObject* pyAr
jstring v = (*jenv)->CallObjectMethodA(jenv, objectRef, method->mid, jArgs);
JPy_ON_JAVA_EXCEPTION_GOTO(error);
returnValue = JPy_FromJString(jenv, v);
(*jenv)->DeleteLocalRef(jenv, v);
JPy_DELETE_LOCAL_REF(v);
} else {
jobject v = (*jenv)->CallObjectMethodA(jenv, objectRef, method->mid, jArgs);
JPy_ON_JAVA_EXCEPTION_GOTO(error);
returnValue = JMethod_FromJObject(jenv, method, pyArgs, jArgs, 1, returnType, v);
(*jenv)->DeleteLocalRef(jenv, v);
JPy_DELETE_LOCAL_REF(v);
}
}

Expand Down
20 changes: 11 additions & 9 deletions src/main/c/jpy_jobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ int JObj_init_internal(JNIEnv* jenv, JPy_JObj* self, PyObject* args, PyObject* k
JPy_JType* jType;
PyObject* constructor;
JPy_JMethod* jMethod;
jobject objectRef;
jobject localObjectRef;
jobject globalObjectRef;
jvalue* jArgs;
JPy_ArgDisposer* jDisposers;
int isVarArgsArray;
Expand Down Expand Up @@ -123,10 +124,10 @@ int JObj_init_internal(JNIEnv* jenv, JPy_JObj* self, PyObject* args, PyObject* k

JPy_DIAG_PRINT(JPy_DIAG_F_MEM, "JObj_init: calling Java constructor %s\n", jType->javaName);

objectRef = (*jenv)->NewObjectA(jenv, jType->classRef, jMethod->mid, jArgs);
localObjectRef = (*jenv)->NewObjectA(jenv, jType->classRef, jMethod->mid, jArgs);
JPy_ON_JAVA_EXCEPTION_RETURN(-1);

if (objectRef == NULL) {
if (localObjectRef == NULL) {
PyErr_NoMemory();
return -1;
}
Expand All @@ -135,18 +136,19 @@ int JObj_init_internal(JNIEnv* jenv, JPy_JObj* self, PyObject* args, PyObject* k
JMethod_DisposeJArgs(jenv, jMethod->paramCount, jArgs, jDisposers);
}

objectRef = (*jenv)->NewGlobalRef(jenv, objectRef);
if (objectRef == NULL) {
globalObjectRef = (*jenv)->NewGlobalRef(jenv, localObjectRef);
if (globalObjectRef == NULL) {
PyErr_NoMemory();
return -1;
}
JPy_DELETE_LOCAL_REF(localObjectRef);

// Note: __init__ may be called multiple times, so we have to release the old objectRef
if (self->objectRef != NULL) {
(*jenv)->DeleteGlobalRef(jenv, self->objectRef);
}

self->objectRef = objectRef;
self->objectRef = globalObjectRef;

JPy_DIAG_PRINT(JPy_DIAG_F_MEM, "JObj_init: self->objectRef=%p\n", self->objectRef);

Expand Down Expand Up @@ -349,7 +351,7 @@ PyObject* JObj_str(JPy_JObj* self)
returnValue = JPy_FromJString(jenv, stringRef);

error:
(*jenv)->DeleteLocalRef(jenv, stringRef);
JPy_DELETE_LOCAL_REF(stringRef);

return returnValue;
}
Expand Down Expand Up @@ -509,7 +511,7 @@ PyObject* JObj_getattro(JPy_JObj* self, PyObject* name)
jobject item = (*jenv)->GetObjectField(jenv, self->objectRef, field->fid);
JPy_ON_JAVA_EXCEPTION_RETURN(NULL);
returnValue = JPy_FromJObjectWithType(jenv, item, field->type);
(*jenv)->DeleteLocalRef(jenv, item);
JPy_DELETE_LOCAL_REF(item);
return returnValue;
}
} else {
Expand Down Expand Up @@ -608,7 +610,7 @@ PyObject* JObj_sq_item(JPy_JObj* self, Py_ssize_t index)
jobject item = (*jenv)->GetObjectArrayElement(jenv, self->objectRef, (jsize) index);
JPy_ON_JAVA_EXCEPTION_RETURN(NULL);
returnValue = JPy_FromJObjectWithType(jenv, item, type->componentType);
(*jenv)->DeleteLocalRef(jenv, item);
JPy_DELETE_LOCAL_REF(item);
return returnValue;
}
}
Expand Down
Loading

0 comments on commit 7959d6f

Please sign in to comment.