sc/source/ui/view/gridwin4.cxx |   37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

New commits:
commit affc777b76e2dde474997a797f4bb46810c98a76
Author:     Dennis Francis <dennis.fran...@collabora.com>
AuthorDate: Tue Dec 7 14:32:57 2021 +0530
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Dec 13 15:59:51 2021 +0100

    lok: don't crash accessing an invalid ObjectContact cache
    
    Fix description:
    
    Avoid storing a reference to the object-contact
    (sdr::contact::ObjectContact) of the page-window (SdrPageWindow) related
    to ScDrawView in the "proxy" object-contact. In the current setup there
    is no way to invalidate the proxy object when the original
    object-contact and its page-window are destroyed (in this case it seems
    during a sheet-switch).  Instead query the real object contact just in
    time when the grid offsets are requested from the proxy object-contact.
    
    Performance:
    
    Behaviour of offset computation is not affected. It is still cached in
    the "real" object contact and it is only computed after it gets
    invalidated (because of change in zoom)
    
    Crasher reproduction(LOK):
    
    1. Create a spreadsheet with two sheets - one with a table of texts and
       shapes and other may be empty.
    2. In first sheet select a single row(via header) and press Ctrl+X.
    3. Go to the empty sheet, and paste (Ctrl+V) and immediately save using
       Ctrl+S.
    
    ---Relevant part of backtrace-----------------
     <signal handler called>
     0x00007ff96781cc70 in main_arena () from /lib64/libc.so.6
     0x00007ff964f2f47b in sdr::contact::ViewObjectContact::getGridOffset 
(this=0x6f01f20) at 
/opt/libreoffice/co-2021/svx/source/sdr/contact/viewobjectcontact.cxx:456
     0x00007ff95cffac5a in (anonymous 
namespace)::ScLOKProxyObjectContact::calculateGridOffsetForViewOjectContact 
(this=0x6fb00a0, rTarget=..., rClient=...) at 
/opt/libreoffice/co-2021/sc/source/ui/view/gridwin4.cxx:1315
     0x00007ff964f2f493 in sdr::contact::ViewObjectContact::getGridOffset 
(this=this@entry=0x5e0c5e0) at 
/opt/libreoffice/co-2021/svx/source/sdr/contact/viewobjectcontact.cxx:459
     0x00007ff964f30732 in 
sdr::contact::ViewObjectContact::getPrimitive2DSequence (this=0x5e0c5e0, 
rDisplayInfo=...) at 
/opt/libreoffice/co-2021/svx/source/sdr/contact/viewobjectcontact.cxx:364
     0x00007ff964f30a82 in sdr::contact::ViewObjectContact::getObjectRange 
(this=0x5e0c5e0) at 
/opt/libreoffice/co-2021/svx/source/sdr/contact/viewobjectcontact.cxx:198
     0x00007ff964f30d00 in sdr::contact::ViewObjectContact::ActionChanged 
(this=0x5e0c5e0) at 
/opt/libreoffice/co-2021/svx/source/sdr/contact/viewobjectcontact.cxx:220
     0x00007ff964f20294 in sdr::contact::ViewContact::ActionChildInserted 
(this=0x5dd83a0, rChild=...) at 
/opt/libreoffice/co-2021/svx/source/sdr/contact/viewcontact.cxx:180
     0x00007ff96506628a in SdrObjList::impChildInserted (rChild=...) at 
/opt/libreoffice/co-2021/svx/source/svdraw/svdpage.cxx:288
     0x00007ff95c808bcd in ScDocument::CreateAllNoteCaptions (this=<optimized 
out>) at /opt/libreoffice/co-2021/sc/source/core/data/document.cxx:6614
     ...
     0x00007ff95cbedcc5 in ScXMLImportWrapper::Export 
(this=this@entry=0x7fff5432f110, bStylesOnly=bStylesOnly@entry=false) at 
/opt/libreoffice/co-2021/sc/source/filter/xml/xmlwrap.cxx:730
     0x00007ff95ccfd896 in ScDocShell::SaveXML (this=0x5c4c330, 
pSaveMedium=<optimized out>, xStor=...) at 
/opt/libreoffice/co-2021/sc/source/ui/docshell/docsh.cxx:556
     0x00007ff95cd009c7 in ScDocShell::SaveAs (this=0x5c4c330, rMedium=...) at 
/opt/libreoffice/co-2021/sc/source/ui/docshell/docsh.cxx:1801
     ...
     0x00007ff95d081af4 in ScTabViewShell::ExecuteSave (this=0x5e9b100, 
rReq=...) at /opt/libreoffice/co-2021/sc/source/ui/inc/viewdata.hxx:354
    -----------------------------------------
    
    Change-Id: I00eac440546624bc448dcd30499957dea7c1de87
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126471
    Tested-by: Jenkins
    Reviewed-by: Dennis Francis <dennis.fran...@collabora.com>
    (cherry picked from commit ff175d858e897964d81cf3b7edaa6ccde32e098b)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126519

diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 07b73255c5eb..5da4a54508d2 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -1330,15 +1330,15 @@ namespace
     class ScLOKProxyObjectContact final : public 
sdr::contact::ObjectContactOfPageView
     {
     private:
-        sdr::contact::ObjectContact& mrRealObjectContact;
+        ScDrawView* mpScDrawView;
 
     public:
         explicit ScLOKProxyObjectContact(
-            sdr::contact::ObjectContact& rRealOC,
+            ScDrawView* pDrawView,
             SdrPageWindow& rPageWindow,
             const char* pDebugName) :
             ObjectContactOfPageView(rPageWindow, pDebugName),
-            mrRealObjectContact(rRealOC)
+            mpScDrawView(pDrawView)
         {
         }
 
@@ -1348,9 +1348,22 @@ namespace
             basegfx::B2DVector& rTarget,
             const sdr::contact::ViewObjectContact& rClient) const override
         {
+            if (!mpScDrawView)
+                return;
+
+            SdrPageView* pPageView(mpScDrawView->GetSdrPageView());
+            if (!pPageView)
+                return;
+
+            SdrPageWindow* pSdrPageWindow = pPageView->GetPageWindow(0);
+            if (!pSdrPageWindow)
+                return;
+
+            sdr::contact::ObjectContact& 
rObjContact(pSdrPageWindow->GetObjectContact());
+
             SdrObject* 
pTargetSdrObject(rClient.GetViewContact().TryToGetSdrObject());
             if (pTargetSdrObject)
-                rTarget = 
pTargetSdrObject->GetViewContact().GetViewObjectContact(mrRealObjectContact).getGridOffset();
+                rTarget = 
pTargetSdrObject->GetViewContact().GetViewObjectContact(rObjContact).getGridOffset();
         }
     };
 
@@ -1359,29 +1372,21 @@ namespace
     public:
         ScLOKDrawView(OutputDevice* pOut, ScViewData& rData) :
             FmFormView(*rData.GetDocument().GetDrawLayer(), pOut),
-            pScDrawView(rData.GetScDrawView())
+            mpScDrawView(rData.GetScDrawView())
         {
         }
 
         virtual sdr::contact::ObjectContact* createViewSpecificObjectContact(
                 SdrPageWindow& rPageWindow, const char* pDebugName) const 
override
         {
-            if (!pScDrawView)
-                return SdrView::createViewSpecificObjectContact(rPageWindow, 
pDebugName);
-
-            SdrPageView* pPageView(pScDrawView->GetSdrPageView());
-            if (!pPageView)
-                return SdrView::createViewSpecificObjectContact(rPageWindow, 
pDebugName);
-
-            SdrPageWindow* pSdrPageWindow = pPageView->GetPageWindow(0);
-            if (!pSdrPageWindow)
+            if (!mpScDrawView)
                 return SdrView::createViewSpecificObjectContact(rPageWindow, 
pDebugName);
 
-            return new 
ScLOKProxyObjectContact(pSdrPageWindow->GetObjectContact(), rPageWindow, 
pDebugName);
+            return new ScLOKProxyObjectContact(mpScDrawView, rPageWindow, 
pDebugName);
         }
 
     private:
-        ScDrawView* pScDrawView;
+        ScDrawView* mpScDrawView;
     };
 } // anonymous namespace
 

Reply via email to