summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Luby <plubius@neooffice.org>2023-06-15 17:10:17 -0400
committerPatrick Luby <plubius@neooffice.org>2023-06-16 18:38:55 +0200
commitb6299c9e56f70ebc124814f4001e149e7be298ad (patch)
tree5d454a42e4e839e46009287bd060476162c0b40b
parent52c34f4e84c5125e2a3c72b57a3c4d30a593debd (diff)
tdf#146626 catch IndexOutOfBoundsException when fetching accessible children
com::sun::star::accessibility::XAccessibleContext::getAccessibleChild() can throw an IndexOutOfBoundsException exception even when fetching with an index that is positive and less than the value returned by a call to the accessible context's getAccessibleChildCount() method so put every getAccessibleChild() call in a try/catch block. Note: this is actually expected behavior even though it is rare. For example, accessibility::AccessibleTextHelper_Impl::getAccessibleChild() uses the following code snippet to throw such an exception: if( 0 > i || i >= getAccessibleChildCount() || GetTextForwarder().GetParagraphCount() <= i ) In the case of tdf#146626, getAccessibleChildCount() returns 22 but getAccessibleChild(1) throws such an exception due to the last condition in the above code snippet. Change-Id: If974afb7b9178faa99b91dcd79eb5f169bbfe13e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153160 Tested-by: Jenkins Reviewed-by: Patrick Luby <plubius@neooffice.org>
-rw-r--r--vcl/osx/a11yfocustracker.cxx30
-rw-r--r--vcl/osx/a11yrolehelper.mm26
-rw-r--r--vcl/osx/a11ywrapper.mm47
-rw-r--r--vcl/osx/documentfocuslistener.cxx44
4 files changed, 101 insertions, 46 deletions
diff --git a/vcl/osx/a11yfocustracker.cxx b/vcl/osx/a11yfocustracker.cxx
index 8d830cdb62a1..2aaa8b0a8e25 100644
--- a/vcl/osx/a11yfocustracker.cxx
+++ b/vcl/osx/a11yfocustracker.cxx
@@ -30,8 +30,10 @@
#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
AquaA11yFocusTracker& TheAquaA11yFocusTracker()
@@ -118,10 +120,16 @@ void AquaA11yFocusTracker::notify_toolbox_item_focus(ToolBox *pToolBox)
if( xContext.is() )
{
- ToolBox::ImplToolItems::size_type nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() );
- if( nPos != ToolBox::ITEM_NOTFOUND )
- setFocusedObject( xContext->getAccessibleChild( nPos ) );
- //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
+ try {
+ ToolBox::ImplToolItems::size_type nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() );
+ if( nPos != ToolBox::ITEM_NOTFOUND )
+ setFocusedObject( xContext->getAccessibleChild( nPos ) );
+ //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
+ }
+ catch (const IndexOutOfBoundsException&)
+ {
+ SAL_WARN("vcl", "Accessible object has invalid index in parent");
+ }
}
}
}
@@ -150,11 +158,17 @@ void AquaA11yFocusTracker::toolbox_open_floater(vcl::Window *pWindow)
return;
}
if ( rxContext -> getAccessibleChildCount() > 0 ) {
- Reference < XAccessible > rxAccessibleChild = rxContext -> getAccessibleChild( 0 );
- if ( ! rxAccessibleChild.is() ) {
- return;
+ try {
+ Reference < XAccessible > rxAccessibleChild = rxContext -> getAccessibleChild( 0 );
+ if ( ! rxAccessibleChild.is() ) {
+ return;
+ }
+ setFocusedObject ( rxAccessibleChild );
+ }
+ catch (const IndexOutOfBoundsException&)
+ {
+ SAL_WARN("vcl", "No valid accessible objects in parent");
}
- setFocusedObject ( rxAccessibleChild );
}
}
}
diff --git a/vcl/osx/a11yrolehelper.mm b/vcl/osx/a11yrolehelper.mm
index 5cb75c94a86f..e95036dbebd9 100644
--- a/vcl/osx/a11yrolehelper.mm
+++ b/vcl/osx/a11yrolehelper.mm
@@ -24,8 +24,12 @@
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+
+#include <sal/log.hxx>
using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
@implementation AquaA11yRoleHelper
@@ -153,17 +157,23 @@ using namespace ::com::sun::star::uno;
}
}
} else if ( accessibleContext -> getAccessibleRole() == AccessibleRole::COMBO_BOX ) {
- Reference < XAccessible > rxAccessible = accessibleContext -> getAccessibleChild(0);
- if ( rxAccessible.is() ) {
- Reference < XAccessibleContext > rxAccessibleContext = rxAccessible -> getAccessibleContext();
- if ( rxAccessibleContext.is() && rxAccessibleContext -> getAccessibleRole() == AccessibleRole::TEXT ) {
- sal_Int64 nStateSet = rxAccessibleContext -> getAccessibleStateSet();
- if ( !(nStateSet & AccessibleStateType::EDITABLE ) ) {
- [ nativeRole release ];
- nativeRole = NSAccessibilityPopUpButtonRole;
+ try {
+ Reference < XAccessible > rxAccessible = accessibleContext -> getAccessibleChild(0);
+ if ( rxAccessible.is() ) {
+ Reference < XAccessibleContext > rxAccessibleContext = rxAccessible -> getAccessibleContext();
+ if ( rxAccessibleContext.is() && rxAccessibleContext -> getAccessibleRole() == AccessibleRole::TEXT ) {
+ sal_Int64 nStateSet = rxAccessibleContext -> getAccessibleStateSet();
+ if ( !(nStateSet & AccessibleStateType::EDITABLE ) ) {
+ [ nativeRole release ];
+ nativeRole = NSAccessibilityPopUpButtonRole;
+ }
}
}
}
+ catch (const IndexOutOfBoundsException&)
+ {
+ SAL_WARN("vcl", "No valid accessible objects in parent");
+ }
}
return nativeRole;
}
diff --git a/vcl/osx/a11ywrapper.mm b/vcl/osx/a11ywrapper.mm
index 06967df5aa3e..0ca256a7552f 100644
--- a/vcl/osx/a11ywrapper.mm
+++ b/vcl/osx/a11ywrapper.mm
@@ -45,6 +45,7 @@
#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <sal/log.hxx>
#include <osl/diagnose.h>
@@ -339,19 +340,25 @@ static std::ostream &operator<<(std::ostream &s, NSObject *obj) {
NSMutableArray * children = [ [ NSMutableArray alloc ] init ];
Reference< XAccessibleContext > xContext( [ self accessibleContext ] );
- sal_Int64 cnt = xContext -> getAccessibleChildCount();
- for ( sal_Int64 i = 0; i < cnt; i++ ) {
- Reference< XAccessible > xChild( xContext -> getAccessibleChild( i ) );
- if( xChild.is() ) {
- Reference< XAccessibleContext > xChildContext( xChild -> getAccessibleContext() );
- // the menubar is already accessible (including Apple- and Application-Menu) through NSApplication => omit it here
- if ( xChildContext.is() && AccessibleRole::MENU_BAR != xChildContext -> getAccessibleRole() ) {
- id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: xChildContext ];
- [ children addObject: wrapper ];
- [ wrapper release ];
+ try {
+ sal_Int64 cnt = xContext -> getAccessibleChildCount();
+ for ( sal_Int64 i = 0; i < cnt; i++ ) {
+ Reference< XAccessible > xChild( xContext -> getAccessibleChild( i ) );
+ if( xChild.is() ) {
+ Reference< XAccessibleContext > xChildContext( xChild -> getAccessibleContext() );
+ // the menubar is already accessible (including Apple- and Application-Menu) through NSApplication => omit it here
+ if ( xChildContext.is() && AccessibleRole::MENU_BAR != xChildContext -> getAccessibleRole() ) {
+ id wrapper = [ AquaA11yFactory wrapperForAccessibleContext: xChildContext ];
+ [ children addObject: wrapper ];
+ [ wrapper release ];
+ }
}
}
}
+ catch (const IndexOutOfBoundsException&)
+ {
+ SAL_WARN("vcl", "Accessible object has invalid index in parent");
+ }
// if not already acting as RadioGroup now is the time to replace RadioButtons with RadioGroups and remove RadioButtons
if ( ! mActsAsRadioGroup ) {
@@ -1063,16 +1070,22 @@ static Reference < XAccessibleContext > hitTestRunner ( css::awt::Point point,
}
if( bSafeToIterate ) {
- for ( sal_Int64 i = 0; i < rxAccessibleContext -> getAccessibleChildCount(); i++ ) {
- Reference < XAccessible > rxAccessibleChild = rxAccessibleContext -> getAccessibleChild ( i );
- if ( rxAccessibleChild.is() && rxAccessibleChild -> getAccessibleContext().is() && rxAccessibleChild -> getAccessibleContext() -> getAccessibleRole() != AccessibleRole::LIST ) {
- Reference < XAccessibleContext > myHitChild = hitTestRunner ( point, rxAccessibleChild -> getAccessibleContext() );
- if ( myHitChild.is() ) {
- hitChild = myHitChild;
- break;
+ try {
+ for ( sal_Int64 i = 0; i < rxAccessibleContext -> getAccessibleChildCount(); i++ ) {
+ Reference < XAccessible > rxAccessibleChild = rxAccessibleContext -> getAccessibleChild ( i );
+ if ( rxAccessibleChild.is() && rxAccessibleChild -> getAccessibleContext().is() && rxAccessibleChild -> getAccessibleContext() -> getAccessibleRole() != AccessibleRole::LIST ) {
+ Reference < XAccessibleContext > myHitChild = hitTestRunner ( point, rxAccessibleChild -> getAccessibleContext() );
+ if ( myHitChild.is() ) {
+ hitChild = myHitChild;
+ break;
+ }
}
}
}
+ catch (const IndexOutOfBoundsException&)
+ {
+ SAL_WARN("vcl", "Accessible object has invalid index in parent");
+ }
}
}
} catch ( RuntimeException ) {
diff --git a/vcl/osx/documentfocuslistener.cxx b/vcl/osx/documentfocuslistener.cxx
index 5f39e7cbfdc0..44a3506f860d 100644
--- a/vcl/osx/documentfocuslistener.cxx
+++ b/vcl/osx/documentfocuslistener.cxx
@@ -106,7 +106,13 @@ Reference< XAccessible > DocumentFocusListener::getAccessible(const EventObject&
Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
if( xParentContext.is() )
{
- return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() );
+ try {
+ return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() );
+ }
+ catch (const IndexOutOfBoundsException&)
+ {
+ SAL_WARN("vcl", "Accessible object has invalid index in parent");
+ }
}
}
}
@@ -153,13 +159,19 @@ void DocumentFocusListener::attachRecursive(
if( ! (nStateSet & AccessibleStateType::MANAGES_DESCENDANTS) )
{
- sal_Int64 n, nmax = xContext->getAccessibleChildCount();
- for( n = 0; n < nmax; n++ )
+ try {
+ sal_Int64 n, nmax = xContext->getAccessibleChildCount();
+ for( n = 0; n < nmax; n++ )
+ {
+ Reference< XAccessible > xChild( xContext->getAccessibleChild( n ) );
+
+ if( xChild.is() )
+ attachRecursive(xChild);
+ }
+ }
+ catch (const IndexOutOfBoundsException&)
{
- Reference< XAccessible > xChild( xContext->getAccessibleChild( n ) );
-
- if( xChild.is() )
- attachRecursive(xChild);
+ SAL_WARN("vcl", "Accessible object index does not exist in parent");
}
}
}
@@ -197,13 +209,19 @@ void DocumentFocusListener::detachRecursive(
if( ! (nStateSet & AccessibleStateType::MANAGES_DESCENDANTS) )
{
- sal_Int64 n, nmax = xContext->getAccessibleChildCount();
- for( n = 0; n < nmax; n++ )
+ try {
+ sal_Int64 n, nmax = xContext->getAccessibleChildCount();
+ for( n = 0; n < nmax; n++ )
+ {
+ Reference< XAccessible > xChild( xContext->getAccessibleChild( n ) );
+
+ if( xChild.is() )
+ detachRecursive(xChild);
+ }
+ }
+ catch (const IndexOutOfBoundsException&)
{
- Reference< XAccessible > xChild( xContext->getAccessibleChild( n ) );
-
- if( xChild.is() )
- detachRecursive(xChild);
+ SAL_WARN("vcl", "Accessible object index does not exist in parent");
}
}
}