From 490b2b4c90fab105c40ec14756de18a13b99f897 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 13 Nov 2024 14:50:18 +0100 Subject: [PATCH] QJniArray: fix local reference leak We get a local reference from New*Array, and then construct a QJniArray from that, which will create a new global reference, without deleting the local reference. Instead, go through QJniObject::fromLocalRef, and release the local reference also in case of failure. Change-Id: I88108315240133369efab30e55fdbea17a17a26d Reviewed-by: Assam Boudjelthia Reviewed-by: Zoltan Gera (cherry picked from commit 37638c84efaf2810ad49da0b987f19287d8c4ad6) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qjniarray.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qjniarray.h b/src/corelib/kernel/qjniarray.h index 7dbd3d475d2..a7dc03694d2 100644 --- a/src/corelib/kernel/qjniarray.h +++ b/src/corelib/kernel/qjniarray.h @@ -578,8 +578,11 @@ auto QJniArrayBase::makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion) const size_type length = size_type(std::size(list)); JNIEnv *env = QJniEnvironment::getJniEnv(); auto localArray = (env->*newArray)(length); - if (QJniEnvironment::checkAndClearExceptions(env)) + if (QJniEnvironment::checkAndClearExceptions(env)) { + if (localArray) + env->DeleteLocalRef(localArray); return QJniArray(); + } if (length) { // can't use static_cast here because we have signed/unsigned mismatches @@ -592,7 +595,7 @@ auto QJniArrayBase::makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion) (env->*setRegion)(localArray, i++, 1, reinterpret_cast(&e)); } } - return QJniArray(localArray); + return QJniArray(QJniObject::fromLocalRef(localArray)); }; template @@ -620,8 +623,11 @@ auto QJniArrayBase::makeObjectArray(List &&list) elementClass = env->GetObjectClass(*std::begin(list)); } auto localArray = env->NewObjectArray(length, elementClass, nullptr); - if (QJniEnvironment::checkAndClearExceptions(env)) + if (QJniEnvironment::checkAndClearExceptions(env)) { + if (localArray) + env->DeleteLocalRef(localArray); return ResultType(); + } // explicitly manage the frame for local references in chunks of 100 QJniObject::LocalFrame frame(env); @@ -640,7 +646,7 @@ auto QJniArrayBase::makeObjectArray(List &&list) } if (i) env->PopLocalFrame(nullptr); - return ResultType(localArray); + return ResultType(QJniObject::fromLocalRef(localArray)); } namespace QtJniTypes