vcl/unx/gtk3/a11y/atkwrapper.cxx |    5 +++++
 1 file changed, 5 insertions(+)

New commits:
commit 957aea0cf9d21909a8488c80ebb272bd91fb30cd
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Nov 19 17:27:20 2024 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Nov 20 11:50:23 2024 +0100

    tdf#155449 gtk3 a11y: Hold reference to the original AtkObject
    
    Let the AtkObjectWrapper hold a reference to the original AtkObject,
    and release it in `atk_object_wrapper_finalize`.
    
    Without this, the original AtkObject might get destroyed
    too early. Then trying to access it would result in a crash.
    
    While occasionally also seen elsewhere, this was somewhat
    more reliably reproducible when starting the Orca screen
    reader or a pyatspi event listener script while the spell
    check dialog in Writer was shown.
    
    Backtrace of how the AtkObject got destroyed (reverse-debugged
    with rr with a data breakpoint on the AtkObject's accessible description):
    
        1  _int_free_create_chunk   malloc.c             4738 0x7fe5766a858e
        2  _int_free_merge_chunk    malloc.c             4700 0x7fe5766a99b8
        3  _int_free                malloc.c             4646 0x7fe5766a9d31
        4  __GI___libc_free         malloc.c             3398 0x7fe5766ac4ff
        5  atk_object_finalize      atkobject.c          1399 0x7fe5626a7785
        6  g_object_unref                                     0x7fe56e9b94ee
        7  expiry_func              accessible-leasing.c 122  0x7fe5624f32b1
        8  ??                                                 0x7fe568f0f88e
        9  ??                                                 0x7fe568f0c7df
        10 ??                                                 0x7fe568f0ea17
        11 g_main_context_iteration                           0x7fe568f0f180
        12 GtkSalData::Yield        gtkdata.cxx          405  0x7fe5634766ec
        13 GtkInstance::DoYield     gtkinst.cxx          425  0x7fe56347b493
        14 ImplYield                svapp.cxx            385  0x7fe56db0e106
        15 Application::Yield       svapp.cxx            473  0x7fe56db0da9f
        16 Application::Execute     svapp.cxx            360  0x7fe56db0d880
        17 desktop::Desktop::Main   app.cxx              1679 0x7fe576926d8b
        18 ImplSVMain               svmain.cxx           228  0x7fe56db2e996
        19 SVMain                   svmain.cxx           246  0x7fe56db30589
        20 soffice_main             sofficemain.cxx      121  0x7fe5769a08da
        21 sal_main                 main.c               51   0x5644db935a6d
        22 main                     main.c               49   0x5644db935a47
    
    Backtrace of the crash when using the already deleted
    object later:
    
        1  g_type_check_instance_cast                             0x7fe56e9d9337
        2  atk_object_get_index_in_parent atkobject.c        1007 0x7fe5626a5ae5
        3  wrapper_get_index_in_parent    atkwrapper.cxx     545  0x7fe56344a244
        4  atk_object_get_index_in_parent atkobject.c        1011 0x7fe5626a5b3c
        5  append_cache_item              cache-adaptor.c    183  0x7fe562500591
        6  append_accessible_hf           cache-adaptor.c    246  0x7fe56250029b
        7  g_hash_table_foreach                                   0x7fe568efacd3
        8  spi_cache_foreach              accessible-cache.c 423  0x7fe5624f33f9
        9  impl_GetItems                  cache-adaptor.c    328  0x7fe562500174
        10 handle_other                   droute.c           558  0x7fe56250f8a4
        11 handle_message                 droute.c           605  0x7fe56250e7d6
        12 ??                                                     0x7fe5764f5e64
        13 dbus_connection_dispatch                               0x7fe5764e58ab
        14 message_queue_dispatch         atspi-gmain.c      89   0x7fe5623abc52
        15 ??                                                     0x7fe568f0c7df
        16 ??                                                     0x7fe568f0ea17
        17 g_main_context_iteration                               0x7fe568f0f180
        18 GtkSalData::Yield              gtkdata.cxx        405  0x7fe5634766ec
        19 GtkInstance::DoYield           gtkinst.cxx        425  0x7fe56347b493
        20 ImplYield                      svapp.cxx          385  0x7fe56db0e106
        21 Application::Yield             svapp.cxx          473  0x7fe56db0da9f
        22 Application::Execute           svapp.cxx          360  0x7fe56db0d880
        23 desktop::Desktop::Main         app.cxx            1679 0x7fe576926d8b
        24 ImplSVMain                     svmain.cxx         228  0x7fe56db2e996
        25 SVMain                         svmain.cxx         246  0x7fe56db30589
        26 soffice_main                   sofficemain.cxx    121  0x7fe5769a08da
        27 sal_main                       main.c             51   0x5644db935a6d
        28 main                           main.c             49   0x5644db935a47
    
    The deleted object is the `AtkObject *accessible` param
    passed to `atk_object_get_index_in_parent`.
    
    This is with at-spi2-core git main as of commit
    422cac4bd657ce783164324e6ae4b3d54a8aa761.
    
    Change-Id: I23d8a3d55bd587aa99316d71524a18afcd6c0479
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176787
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    (cherry picked from commit 357f040d36c4bdebb59c9ada1a2ee20423ca2155)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176811
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/vcl/unx/gtk3/a11y/atkwrapper.cxx b/vcl/unx/gtk3/a11y/atkwrapper.cxx
index b83cf04d48b5..3fe2d388891c 100644
--- a/vcl/unx/gtk3/a11y/atkwrapper.cxx
+++ b/vcl/unx/gtk3/a11y/atkwrapper.cxx
@@ -667,6 +667,9 @@ atk_object_wrapper_finalize (GObject *obj)
 
     atk_object_wrapper_dispose( pWrap );
 
+    if (pWrap->mpOrig)
+        g_object_unref(pWrap->mpOrig);
+
     parent_class->finalize( obj );
 }
 
@@ -962,6 +965,8 @@ atk_object_wrapper_new( const css::uno::Reference< 
css::accessibility::XAccessib
 
         pWrap->mpContext = xContext;
         pWrap->mpOrig = orig;
+        if (pWrap->mpOrig)
+            g_object_ref(pWrap->mpOrig);
 
         AtkObject* atk_obj = ATK_OBJECT(pWrap);
         atk_obj->role = mapToAtkRole(xContext->getAccessibleRole(), 
xContext->getAccessibleStateSet());

Reply via email to