vcl/unx/gtk3/a11y/atkwrapper.cxx |    5 +++++
 vcl/unx/gtk3/gtkinst.cxx         |    4 +---
 2 files changed, 6 insertions(+), 3 deletions(-)

New commits:
commit 357f040d36c4bdebb59c9ada1a2ee20423ca2155
Author:     Michael Weghorn <[email protected]>
AuthorDate: Tue Nov 19 17:27:20 2024 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Wed Nov 20 07:56:38 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 <[email protected]>

diff --git a/vcl/unx/gtk3/a11y/atkwrapper.cxx b/vcl/unx/gtk3/a11y/atkwrapper.cxx
index 4cff5dd6c176..6c71c40d0ed3 100644
--- a/vcl/unx/gtk3/a11y/atkwrapper.cxx
+++ b/vcl/unx/gtk3/a11y/atkwrapper.cxx
@@ -674,6 +674,9 @@ atk_object_wrapper_finalize (GObject *obj)
 
     atk_object_wrapper_dispose( pWrap );
 
+    if (pWrap->mpOrig)
+        g_object_unref(pWrap->mpOrig);
+
     parent_class->finalize( obj );
 }
 
@@ -969,6 +972,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());
commit 657873772c2ab37eca2558950c3515458c21f2c5
Author:     Michael Weghorn <[email protected]>
AuthorDate: Tue Nov 19 17:20:11 2024 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Wed Nov 20 07:56:32 2024 +0100

    gtk3 a11y: Simplify gtk3/gtk4 version check
    
    One gtk3-specific section is sufficient.
    
    Change-Id: I42a5cd1b94df7874665743a386af8e2e19590b0c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176786
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index c3205805cada..f7c220273417 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -18839,11 +18839,9 @@ public:
 
     virtual AbsoluteScreenPixelPoint get_accessible_location_on_screen() 
override
     {
-#if !GTK_CHECK_VERSION(4, 0, 0)
-        AtkObject* pAtkObject = default_drawing_area_get_accessible(m_pWidget);
-#endif
         gint x(0), y(0);
 #if !GTK_CHECK_VERSION(4, 0, 0)
+        AtkObject* pAtkObject = default_drawing_area_get_accessible(m_pWidget);
         if (pAtkObject && ATK_IS_COMPONENT(pAtkObject))
             atk_component_get_extents(ATK_COMPONENT(pAtkObject), &x, &y, 
nullptr, nullptr, ATK_XY_SCREEN);
 #endif

Reply via email to