diff options
author | Dennis Francis <dennis.francis@collabora.com> | 2021-12-07 14:32:57 +0530 |
---|---|---|
committer | Dennis Francis <dennis.francis@collabora.com> | 2021-12-09 07:53:26 +0100 |
commit | ff175d858e897964d81cf3b7edaa6ccde32e098b (patch) | |
tree | 8c0c3a55afb94dc8a32a7022e8622ee18b97580e | |
parent | bf38dd800e6e4e820a0cef84e082d9bcee8e8133 (diff) |
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.francis@collabora.com>
-rw-r--r-- | sc/source/ui/view/gridwin4.cxx | 37 |
1 files changed, 21 insertions, 16 deletions
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 |