tdf#155149 Crash when exiting cell edit mode

regression from
    commit 2dc240a82646fc23c673a6fd5a29ade934dd5b67
    Author: Noel Grandin <noel.grandin@collabora.co.uk>
    Date:   Tue May 2 14:47:43 2023 +0200
    improve AccessibleEventNotifier::addEvent
and
    commit 3b7db802731826b6cc3b55100470b0c61c1f2dfa
    Author: Noel Grandin <noel.grandin@collabora.co.uk>
    Date:   Thu May 4 10:06:14 2023 +0200
    tdf#105404 [API CHANGE] add index to accessiblity change event

(*) Send better index hints
(*) Error check the index hints better
(*) Convert asserts to warnings and fall back to old code when
    index hint is wrong.

Change-Id: I8e752fc26e729c9c8926beb2c7b196f5418a147e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151419
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/comphelper/source/misc/accessiblecomponenthelper.cxx b/comphelper/source/misc/accessiblecomponenthelper.cxx
index 816b3b6..07d05d3 100644
--- a/comphelper/source/misc/accessiblecomponenthelper.cxx
+++ b/comphelper/source/misc/accessiblecomponenthelper.cxx
@@ -113,7 +113,7 @@ namespace comphelper


    void OCommonAccessibleComponent::NotifyAccessibleEvent( const sal_Int16 _nEventId,
        const Any& _rOldValue, const Any& _rNewValue )
        const Any& _rOldValue, const Any& _rNewValue, sal_Int32 nIndexHint )
    {
        if ( !m_nClientId )
            // if we don't have a client id for the notifier, then we don't have listeners, then
@@ -126,6 +126,7 @@ namespace comphelper
        aEvent.EventId = _nEventId;
        aEvent.OldValue = _rOldValue;
        aEvent.NewValue = _rNewValue;
        aEvent.IndexHint = nIndexHint;

        // let the notifier handle this event
        AccessibleEventNotifier::addEvent( m_nClientId, aEvent );
diff --git a/comphelper/source/misc/accessibleeventnotifier.cxx b/comphelper/source/misc/accessibleeventnotifier.cxx
index d146d11..37c9edd 100644
--- a/comphelper/source/misc/accessibleeventnotifier.cxx
+++ b/comphelper/source/misc/accessibleeventnotifier.cxx
@@ -246,8 +246,21 @@ void AccessibleEventNotifier::addEvent( const TClientId _nClient, const Accessib
        return;

    // since we're synchronous, again, we want to notify immediately
    aClientPos->second.notifyEach(aGuard, &XAccessibleEventListener::notifyEvent, _rEvent);

    OInterfaceIteratorHelper4 aIt(aGuard, aClientPos->second);
    // no need to hold lock here, and we don't want to hold lock while calling listeners
    aGuard.unlock();
    while (aIt.hasMoreElements())
    {
        try
        {
            aIt.next()->notifyEvent(_rEvent);
        }
        catch (Exception&)
        {
            // no assertion, because a broken access remote bridge or something like this
            // can cause this exception
        }
    }
}

} // namespace comphelper
diff --git a/include/comphelper/accessiblecomponenthelper.hxx b/include/comphelper/accessiblecomponenthelper.hxx
index 2a840ea..328d613 100644
--- a/include/comphelper/accessiblecomponenthelper.hxx
+++ b/include/comphelper/accessiblecomponenthelper.hxx
@@ -128,7 +128,8 @@ namespace comphelper
        void NotifyAccessibleEvent(
                    const sal_Int16 _nEventId,
                    const css::uno::Any& _rOldValue,
                    const css::uno::Any& _rNewValue
                    const css::uno::Any& _rNewValue,
                    sal_Int32 nIndexHint = -1
                );

        // life time control
diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx
index 6d5dace..87085169 100644
--- a/sc/source/ui/Accessibility/AccessibleDocument.cxx
+++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx
@@ -2136,6 +2136,7 @@ void ScAccessibleDocument::AddChild(const uno::Reference<XAccessible>& xAcc, boo
            aEvent.Source = uno::Reference<XAccessibleContext>(this);
            aEvent.EventId = AccessibleEventId::CHILD;
            aEvent.NewValue <<= mxTempAcc;
            aEvent.IndexHint = getAccessibleChildCount() - 1;
            CommitChange( aEvent );
        }
    }
@@ -2154,6 +2155,7 @@ void ScAccessibleDocument::RemoveChild(const uno::Reference<XAccessible>& xAcc, 
        aEvent.Source = uno::Reference<XAccessibleContext>(this);
        aEvent.EventId = AccessibleEventId::CHILD;
        aEvent.OldValue <<= mxTempAcc;
        aEvent.IndexHint = -1;
        CommitChange( aEvent );
    }
    mxTempAcc = nullptr;
diff --git a/vcl/unx/gtk3/a11y/atklistener.cxx b/vcl/unx/gtk3/a11y/atklistener.cxx
index b0f09114..57f40af 100644
--- a/vcl/unx/gtk3/a11y/atklistener.cxx
+++ b/vcl/unx/gtk3/a11y/atklistener.cxx
@@ -171,16 +171,23 @@ void AtkListener::handleChildAdded(
    if( !pChild )
        return;

    bool bNeedToFullFullChildList = true;
    if (nIndexHint != -1)
    {
        bNeedToFullFullChildList = false;
        sal_Int64 nStateSet = rxParent->getAccessibleStateSet();
        if( !(nStateSet & accessibility::AccessibleStateType::DEFUNC)
              || (nStateSet & accessibility::AccessibleStateType::MANAGES_DESCENDANTS) )
        {
            m_aChildList.insert(m_aChildList.begin() + nIndexHint, rxAccessible);
            if (m_aChildList[nIndexHint] != rxParent->getAccessibleChild(nIndexHint))
            {
                SAL_WARN("vcl", "wrong index hint, falling back to updating full child list");
                bNeedToFullFullChildList = true;
            }
        }
    }
    else
    if (bNeedToFullFullChildList)
        updateChildList(rxParent);

    atk_object_wrapper_add_child( mpWrapper, pChild,
@@ -197,20 +204,32 @@ void AtkListener::handleChildRemoved(
    int nChildIndexHint)
{
    sal_Int32 nIndex = nChildIndexHint;

    // Locate the child in the children list
    const size_t nmax = m_aChildList.size();
    for( size_t n = 0; n < nmax; ++n )
    if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(m_aChildList.size()))
    {
        // Comparing via uno::Reference::operator== is expensive
        // with lots of objects, so assume we can find it the cheap way
        // first, which works most of the time.
        if( rxChild.get() == m_aChildList[n].get() )
        {
            nIndex = n;
            break;
        }
        SAL_WARN("vcl", "index hint out of range, ignoring");
        nIndex = -1;
    }
    if (nIndex != -1 && rxChild != m_aChildList[nIndex])
    {
        SAL_WARN("vcl", "index hint points to wrong child, somebody forgot to send accessibility update event");
        nIndex = -1;
    }

    // if the hint did not work, search
    const size_t nmax = m_aChildList.size();
    if (nIndex == -1)
        // Locate the child in the children list
        for( size_t n = 0; n < nmax; ++n )
        {
            // Comparing via uno::Reference::operator== is expensive
            // with lots of objects, so assume we can find it the cheap way
            // first, which works most of the time.
            if( rxChild.get() == m_aChildList[n].get() )
            {
                nIndex = n;
                break;
            }
        }
    // The cheap way failed, find it via the more expensive path
    if (nIndex == -1)
        for( size_t n = 0; n < nmax; ++n )
@@ -248,7 +267,6 @@ void AtkListener::handleChildRemoved(
    if(!( (nStateSet & accessibility::AccessibleStateType::DEFUNC)
        || (nStateSet & accessibility::AccessibleStateType::MANAGES_DESCENDANTS) ))
    {
        assert( m_aChildList[nIndex] == rxParent->getAccessibleChild(nIndex) );
        m_aChildList.erase(m_aChildList.begin() + nIndex);
    }