Android Accessibility: protect from accessing invalid interfaces

I am not sure if this is going to help, but it is required that the
bridge checks that the interfaces it accesses are valid, since that
protects from accessing them when they are in the destructor.
This should be done, whether it fixes the issue or not.

Task-number: QTBUG-45855
Change-Id: I2b96999ca4043f8b33607c864d1d178695d03192
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Frederik Gladhorn 2017-09-29 10:52:36 +02:00
parent b16add0dc6
commit 8fcf171b42

View File

@ -104,11 +104,11 @@ namespace QtAndroidAccessibility
static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId) static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
{ {
QAccessibleInterface *iface = interfaceFromId(objectId); QAccessibleInterface *iface = interfaceFromId(objectId);
if (iface) { if (iface && iface->isValid()) {
jintArray jArray = env->NewIntArray(jsize(iface->childCount())); jintArray jArray = env->NewIntArray(jsize(iface->childCount()));
for (int i = 0; i < iface->childCount(); ++i) { for (int i = 0; i < iface->childCount(); ++i) {
QAccessibleInterface *child = iface->child(i); QAccessibleInterface *child = iface->child(i);
if (child) { if (child && child->isValid()) {
QAccessible::Id ifaceId = QAccessible::uniqueId(child); QAccessible::Id ifaceId = QAccessible::uniqueId(child);
jint jid = ifaceId; jint jid = ifaceId;
env->SetIntArrayRegion(jArray, i, 1, &jid); env->SetIntArrayRegion(jArray, i, 1, &jid);
@ -123,9 +123,9 @@ namespace QtAndroidAccessibility
static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId) static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
{ {
QAccessibleInterface *iface = interfaceFromId(objectId); QAccessibleInterface *iface = interfaceFromId(objectId);
if (iface) { if (iface && iface->isValid()) {
QAccessibleInterface *parent = iface->parent(); QAccessibleInterface *parent = iface->parent();
if (parent) { if (parent && parent->isValid()) {
if (parent->role() == QAccessible::Application) if (parent->role() == QAccessible::Application)
return -1; return -1;
return QAccessible::uniqueId(parent); return QAccessible::uniqueId(parent);
@ -151,7 +151,7 @@ namespace QtAndroidAccessibility
static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y) static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y)
{ {
QAccessibleInterface *root = interfaceFromId(-1); QAccessibleInterface *root = interfaceFromId(-1);
if (root) { if (root && root->isValid()) {
QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window()); QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window());
QAccessibleInterface *child = root->childAt(pos.x(), pos.y()); QAccessibleInterface *child = root->childAt(pos.x(), pos.y());
@ -170,7 +170,7 @@ namespace QtAndroidAccessibility
{ {
// qDebug() << "A11Y: CLICK: " << objectId; // qDebug() << "A11Y: CLICK: " << objectId;
QAccessibleInterface *iface = interfaceFromId(objectId); QAccessibleInterface *iface = interfaceFromId(objectId);
if (iface && iface->actionInterface()) { if (iface && iface->isValid() && iface->actionInterface()) {
if (iface->actionInterface()->actionNames().contains(QAccessibleActionInterface::pressAction())) if (iface->actionInterface()->actionNames().contains(QAccessibleActionInterface::pressAction()))
iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction()); iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction());
else else
@ -182,13 +182,17 @@ namespace QtAndroidAccessibility
static jboolean scrollForward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId) static jboolean scrollForward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
{ {
QAccessibleInterface *iface = interfaceFromId(objectId); QAccessibleInterface *iface = interfaceFromId(objectId);
if (iface && iface->isValid())
return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::increaseAction()); return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::increaseAction());
return false;
} }
static jboolean scrollBackward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId) static jboolean scrollBackward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
{ {
QAccessibleInterface *iface = interfaceFromId(objectId); QAccessibleInterface *iface = interfaceFromId(objectId);
if (iface && iface->isValid())
return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::decreaseAction()); return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::decreaseAction());
return false;
} }