JNI: check for pending exception first in getCleanJniObject()
returning early if the object is null will not clear pending exceptions from the previous failed JNI call, and that will crash the app on the next jni call if an explicit exception clearing is not done, wish mostly the case. Checking and clearing for exceptions has to always be done under this call. Fixes: QTBUG-122135 Change-Id: I0d42d012a4d1305fa07147fd22860d7c005f9b83 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> (cherry picked from commit 0a4599637657375517fcaf35177d8c7bac302556)
This commit is contained in:
parent
32270a1276
commit
4444167c16
@ -346,11 +346,9 @@ static jclass getCachedClass(const QByteArray &className)
|
||||
*/
|
||||
static QJniObject getCleanJniObject(jobject object, JNIEnv *env)
|
||||
{
|
||||
if (!object)
|
||||
return QJniObject();
|
||||
|
||||
if (QJniEnvironment::checkAndClearExceptions(env)) {
|
||||
env->DeleteLocalRef(object);
|
||||
if (QJniEnvironment::checkAndClearExceptions(env) || !object) {
|
||||
if (object)
|
||||
env->DeleteLocalRef(object);
|
||||
return QJniObject();
|
||||
}
|
||||
|
||||
|
@ -319,4 +319,12 @@ public class QtJniObjectTestClass
|
||||
{
|
||||
return callbackWithDouble(value);
|
||||
}
|
||||
|
||||
public Object callMethodThrowsException() throws Exception {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
public static Object callStaticMethodThrowsException() throws Exception {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,12 @@ private slots:
|
||||
|
||||
void ctor();
|
||||
void callMethodTest();
|
||||
void callMethodThrowsException();
|
||||
void callObjectMethodTest();
|
||||
void stringConvertionTest();
|
||||
void compareOperatorTests();
|
||||
void className();
|
||||
void callStaticMethodThrowsException();
|
||||
void callStaticObjectMethodClassName();
|
||||
void callStaticObjectMethod();
|
||||
void callStaticObjectMethodById();
|
||||
@ -262,6 +264,15 @@ void tst_QJniObject::callMethodTest()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QJniObject::callMethodThrowsException()
|
||||
{
|
||||
QtJniTypes::QtJniObjectTestClass instance;
|
||||
QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.Exception"));
|
||||
auto res = instance.callMethod<jobject>("callMethodThrowsException");
|
||||
QVERIFY(!res.isValid());
|
||||
QVERIFY(!QJniEnvironment().checkAndClearExceptions());
|
||||
}
|
||||
|
||||
void tst_QJniObject::callObjectMethodTest()
|
||||
{
|
||||
const QString qString = QLatin1String("Hello, Java");
|
||||
@ -339,6 +350,15 @@ void tst_QJniObject::className()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QJniObject::callStaticMethodThrowsException()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.Exception"));
|
||||
auto res = QtJniTypes::QtJniObjectTestClass::callStaticMethod<jobject>(
|
||||
"callStaticMethodThrowsException");
|
||||
QVERIFY(!res.isValid());
|
||||
QVERIFY(!QJniEnvironment().checkAndClearExceptions());
|
||||
}
|
||||
|
||||
void tst_QJniObject::callStaticObjectMethodClassName()
|
||||
{
|
||||
QJniObject formatString = QJniObject::fromString(QLatin1String("test format"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user