diff options
author | Caolán McNamara <caolanm@redhat.com> | 2016-06-02 11:18:02 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-06-03 14:47:02 +0000 |
commit | fb433b7909d049f12e848ad56ae8b406f91e1cc2 (patch) | |
tree | 2ed2b714662e301ec73bc9c2df4236f95e8b7267 /sc | |
parent | 1fe53fce9a0776d935fabbdf86b2c03d23da0e72 (diff) |
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@libreoffice.org>
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Eike Rathke <erack@redhat.com>
(cherry picked from commit dc78e5c6f5f55b0289012f4c4e6013d2935b1cc6)
Reviewed-on: https://gerrit.libreoffice.org/25867
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/document.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/grouptokenconverter.cxx | 18 | ||||
-rw-r--r-- | sc/source/core/inc/grouptokenconverter.hxx | 1 |
5 files changed, 24 insertions, 5 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 194fc7d319d7..16db763999d9 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -290,7 +290,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; @@ -924,7 +924,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 8c15aaebbf63..2287b3b2fc18 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -2550,7 +2550,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 c0f4fa3a57e2..721877feb26f 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -3442,12 +3442,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 de3fbf2d2bd0..7b31e3543f4d 100644 --- a/sc/source/core/data/grouptokenconverter.cxx +++ b/sc/source/core/data/grouptokenconverter.cxx @@ -135,6 +135,15 @@ bool ScGroupTokenConverter::convert(ScTokenArray& rCode, std::vector<ScTokenArra 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, std::vector<ScTokenArra 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 b2213636a151..7a3b0cab0194 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; |