[Libreoffice-commits] core.git: sc/inc sc/source

Caolán McNamara caolanm at redhat.com
Fri Jun 3 14:07:13 UTC 2016


 sc/inc/document.hxx                         |    4 ++--
 sc/source/core/data/column2.cxx             |    2 +-
 sc/source/core/data/document.cxx            |    4 ++--
 sc/source/core/data/grouptokenconverter.cxx |   18 ++++++++++++++++++
 sc/source/core/inc/grouptokenconverter.hxx  |    1 +
 5 files changed, 24 insertions(+), 5 deletions(-)

New commits:
commit dc78e5c6f5f55b0289012f4c4e6013d2935b1cc6
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Jun 2 11:18:02 2016 +0100

    Resolves: tdf#98880 ensure backing context of DoubleVectorRefToken...
    
    exists for the lifetime of the ScGroupTokenConverter
    
    otherwise in tdf#98880 ScDocument::InterpretDirtyCells releases
    that backing storage that the DoubleVectorRefToken relies on, and
    the ScVectorRefMatrix relies on that, so...
    
    when sc/source/core/tool/interpr4.cxx calls ::IsString on the ScVectorRefMatrix
    which calls ensureFullMatrix. That makes use of rArray.mpStringArray where
    rArray's mpStringArray is set to that rArray by
    FormulaGroupContext::ensureStrArray and the storage of mpStringArray belongs to
    the FormulaGroupContext, but that context was reset and destroyed up the stack
    in ScDocument::InterpretDirtyCells so the data is now invalid
    
    We could turn the unique_ptr into a shared_ptr and have the ScGroupTokenConverter
    take a ref to the currently active FormulaGroupContext to ensure any generated
    DoubleVectorRefToken/SingleVectorRefToken point to valid data during the
    lifetime of the ScGroupTokenConverter
    
    Change-Id: Id457934cdff18570961cb261cf5c46b6ef8ea083
    Reviewed-on: https://gerrit.libreoffice.org/25815
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index e0237ac..f860dbc 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -299,7 +299,7 @@ private:
     rtl::Reference<ScPoolHelper> xPoolHelper;
 
     std::shared_ptr<svl::SharedStringPool> mpCellStringPool;
-    std::unique_ptr<sc::FormulaGroupContext> mpFormulaGroupCxt;
+    std::shared_ptr<sc::FormulaGroupContext> mpFormulaGroupCxt;
     mutable std::unique_ptr<sc::DocumentLinkManager> mpDocLinkMgr;
 
     ScCalcConfig        maCalcConfig;
@@ -1050,7 +1050,7 @@ public:
 
     svl::SharedString GetSharedString( const ScAddress& rPos ) const;
 
-    sc::FormulaGroupContext& GetFormulaGroupContext();
+    std::shared_ptr<sc::FormulaGroupContext>& GetFormulaGroupContext();
 
     SC_DLLPUBLIC void GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString );
     sal_uInt16 GetStringForFormula( const ScAddress& rPos, OUString& rString );
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 19a7aed..a32b2f7 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2560,7 +2560,7 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( SCROW nRow1, SCROW nRow2
         return formula::VectorRefArray(formula::VectorRefArray::Invalid);
 
     // See if the requested range is already cached.
-    sc::FormulaGroupContext& rCxt = pDocument->GetFormulaGroupContext();
+    sc::FormulaGroupContext& rCxt = *(pDocument->GetFormulaGroupContext());
     sc::FormulaGroupContext::ColArray* pColArray = rCxt.getCachedColArray(nTab, nCol, nRow2+1);
     if (pColArray)
     {
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f9f3933..2fcce07 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3443,12 +3443,12 @@ svl::SharedString ScDocument::GetSharedString( const ScAddress& rPos ) const
     return maTabs[rPos.Tab()]->GetSharedString(rPos.Col(), rPos.Row());
 }
 
-sc::FormulaGroupContext& ScDocument::GetFormulaGroupContext()
+std::shared_ptr<sc::FormulaGroupContext>& ScDocument::GetFormulaGroupContext()
 {
     if (!mpFormulaGroupCxt)
         mpFormulaGroupCxt.reset(new sc::FormulaGroupContext);
 
-    return *mpFormulaGroupCxt;
+    return mpFormulaGroupCxt;
 }
 
 void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString )
diff --git a/sc/source/core/data/grouptokenconverter.cxx b/sc/source/core/data/grouptokenconverter.cxx
index da3964c..22b89a6 100644
--- a/sc/source/core/data/grouptokenconverter.cxx
+++ b/sc/source/core/data/grouptokenconverter.cxx
@@ -135,6 +135,15 @@ bool ScGroupTokenConverter::convert(ScTokenArray& rCode)
 
                     formula::SingleVectorRefToken aTok(aArray, nLen, nTrimLen);
                     mrGroupTokens.AddToken(aTok);
+
+                    if (nTrimLen && !mxFormulaGroupContext)
+                    {
+                        //tdf#98880 if the SingleVectorRefToken relies on the
+                        //underlying storage provided by the Document
+                        //FormulaGroupContext, take a reference to it here to
+                        //ensure that backing storage exists for our lifetime
+                        mxFormulaGroupContext = mrDoc.GetFormulaGroupContext();
+                    }
                 }
                 else
                 {
@@ -210,6 +219,15 @@ bool ScGroupTokenConverter::convert(ScTokenArray& rCode)
 
                 formula::DoubleVectorRefToken aTok(aArrays, nRequestedLength, nArrayLength, nRefRowSize, bAbsFirst, bAbsLast);
                 mrGroupTokens.AddToken(aTok);
+
+                if (nArrayLength && !aArrays.empty() && !mxFormulaGroupContext)
+                {
+                    //tdf#98880 if the DoubleVectorRefToken relies on the
+                    //underlying storage provided by the Document
+                    //FormulaGroupContext, take a reference to it here to
+                    //ensure that backing storage exists for our lifetime
+                    mxFormulaGroupContext = mrDoc.GetFormulaGroupContext();
+                }
             }
             break;
             case svIndex:
diff --git a/sc/source/core/inc/grouptokenconverter.hxx b/sc/source/core/inc/grouptokenconverter.hxx
index 9685681..7b88004 100644
--- a/sc/source/core/inc/grouptokenconverter.hxx
+++ b/sc/source/core/inc/grouptokenconverter.hxx
@@ -20,6 +20,7 @@ class SC_DLLPUBLIC ScGroupTokenConverter
 {
     ScTokenArray& mrGroupTokens;
     ScDocument& mrDoc;
+    std::shared_ptr<sc::FormulaGroupContext> mxFormulaGroupContext;
     ScFormulaCell& mrCell;
     const ScAddress& mrPos;
 


More information about the Libreoffice-commits mailing list