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. Pick-to: 6.8 Change-Id: I88108315240133369efab30e55fdbea17a17a26d Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> Reviewed-by: Zoltan Gera <zoltan.gera@qt.io>
This commit is contained in:
parent
c034ffd527
commit
37638c84ef
@ -875,8 +875,11 @@ auto QJniArrayBase::makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion)
|
|||||||
const size_type length = size_type(std::size(list));
|
const size_type length = size_type(std::size(list));
|
||||||
JNIEnv *env = QJniEnvironment::getJniEnv();
|
JNIEnv *env = QJniEnvironment::getJniEnv();
|
||||||
auto localArray = (env->*newArray)(length);
|
auto localArray = (env->*newArray)(length);
|
||||||
if (QJniEnvironment::checkAndClearExceptions(env))
|
if (QJniEnvironment::checkAndClearExceptions(env)) {
|
||||||
|
if (localArray)
|
||||||
|
env->DeleteLocalRef(localArray);
|
||||||
return QJniArray<ElementType>();
|
return QJniArray<ElementType>();
|
||||||
|
}
|
||||||
|
|
||||||
if (length) {
|
if (length) {
|
||||||
// can't use static_cast here because we have signed/unsigned mismatches
|
// can't use static_cast here because we have signed/unsigned mismatches
|
||||||
@ -889,7 +892,7 @@ auto QJniArrayBase::makeArray(List &&list, NewFn &&newArray, SetFn &&setRegion)
|
|||||||
(env->*setRegion)(localArray, i++, 1, reinterpret_cast<const ElementType *>(&e));
|
(env->*setRegion)(localArray, i++, 1, reinterpret_cast<const ElementType *>(&e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QJniArray<ElementType>(localArray);
|
return QJniArray<ElementType>(QJniObject::fromLocalRef(localArray));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename List>
|
template <typename List>
|
||||||
@ -917,8 +920,11 @@ auto QJniArrayBase::makeObjectArray(List &&list)
|
|||||||
elementClass = env->GetObjectClass(*std::begin(list));
|
elementClass = env->GetObjectClass(*std::begin(list));
|
||||||
}
|
}
|
||||||
auto localArray = env->NewObjectArray(length, elementClass, nullptr);
|
auto localArray = env->NewObjectArray(length, elementClass, nullptr);
|
||||||
if (QJniEnvironment::checkAndClearExceptions(env))
|
if (QJniEnvironment::checkAndClearExceptions(env)) {
|
||||||
|
if (localArray)
|
||||||
|
env->DeleteLocalRef(localArray);
|
||||||
return ResultType();
|
return ResultType();
|
||||||
|
}
|
||||||
|
|
||||||
// explicitly manage the frame for local references in chunks of 100
|
// explicitly manage the frame for local references in chunks of 100
|
||||||
QJniObject::LocalFrame frame(env);
|
QJniObject::LocalFrame frame(env);
|
||||||
@ -937,7 +943,7 @@ auto QJniArrayBase::makeObjectArray(List &&list)
|
|||||||
}
|
}
|
||||||
if (i)
|
if (i)
|
||||||
env->PopLocalFrame(nullptr);
|
env->PopLocalFrame(nullptr);
|
||||||
return ResultType(localArray);
|
return ResultType(QJniObject::fromLocalRef(localArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace QtJniTypes
|
namespace QtJniTypes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user