Accessibility Windows: always check for negative child ids

Some screen readers will pass in child id's that are negative
as response to notifications.
We should always check for negative id's on incoming calls.

Task-number: QTBUG-30792
Change-Id: Idaba3d1931d35ed068cfd9f20e70aa26da427616
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
bb10
Frederik Gladhorn 2013-04-22 15:53:27 +02:00 committed by The Qt Project
parent bc4fbcd215
commit e5e54a9ceb
2 changed files with 21 additions and 26 deletions

View File

@ -721,22 +721,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildI
if (varChildID.vt != VT_I4)
return E_INVALIDARG;
int childIndex = varChildID.lVal;
QAccessibleInterface *acc = 0;
if (childIndex == 0) {
// Yes, some AT clients (Active Accessibility Object Inspector)
// actually ask for the same object. As a consequence, we need to clone ourselves:
acc = accessible;
} else if (childIndex < 0) {
acc = QAccessible::accessibleInterface((QAccessible::Id)childIndex);
} else {
acc = accessible->child(childIndex - 1);
}
QAccessibleInterface *acc = childPointer(accessible, varChildID);
if (acc) {
*ppdispChild = QWindowsAccessibility::wrap(acc);
return S_OK;
@ -825,7 +810,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDescription(VARIANT var
QString descr;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
descr = child->text(QAccessible::Description);
@ -850,7 +835,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelp(VARIANT varID, BST
QString help;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
help = child->text(QAccessible::Help);
@ -909,7 +894,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accName(VARIANT varID, BST
QString name;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
name = child->text(QAccessible::Name);
@ -952,7 +937,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accRole(VARIANT varID, VAR
QAccessible::Role role;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
role = child->role();
@ -987,7 +972,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VA
QAccessible::State state;
if (varID.lVal) {
QAccessibleInterface *child = childPointer(varID);
QAccessibleInterface *child = childPointer(accessible, varID);
if (!child)
return E_FAIL;
state = child->state();

View File

@ -153,13 +153,23 @@ protected:
return 0;
}
QAccessibleInterface *childPointer(VARIANT varID)
static QAccessibleInterface *childPointer(QAccessibleInterface *parent, VARIANT varID)
{
// -1 since windows API always uses 1 for the first child
QAccessibleInterface *iface = accessibleInterface();
if (iface)
return accessibleInterface()->child(varID.lVal - 1);
return 0;
Q_ASSERT(parent);
QAccessibleInterface *acc = 0;
int childIndex = varID.lVal;
if (childIndex == 0) {
// Yes, some AT clients (Active Accessibility Object Inspector)
// actually ask for the same object. As a consequence, we need to clone ourselves:
acc = parent;
} else if (childIndex < 0) {
acc = QAccessible::accessibleInterface((QAccessible::Id)childIndex);
} else {
acc = parent->child(childIndex - 1);
}
return acc;
}
private: