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 <assam.boudjelthia@qt.io>
Reviewed-by: Zoltan Gera <zoltan.gera@qt.io>
(cherry picked from commit 37638c84efaf2810ad49da0b987f19287d8c4ad6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Volker Hilsheimer 2024-11-13 14:50:18 +01:00 committed by Qt Cherry-pick Bot
parent e50c29da84
commit 490b2b4c90

View File

@ -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<ElementType>();
}
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<const ElementType *>(&e));
}
}
return QJniArray<ElementType>(localArray);
return QJniArray<ElementType>(QJniObject::fromLocalRef(localArray));
};
template <typename List>
@ -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