summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2016-06-02 11:18:02 +0100
committerCaolán McNamara <caolanm@redhat.com>2016-06-03 14:47:02 +0000
commitfb433b7909d049f12e848ad56ae8b406f91e1cc2 (patch)
tree2ed2b714662e301ec73bc9c2df4236f95e8b7267 /sc
parent1fe53fce9a0776d935fabbdf86b2c03d23da0e72 (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.hxx4
-rw-r--r--sc/source/core/data/column2.cxx2
-rw-r--r--sc/source/core/data/document.cxx4
-rw-r--r--sc/source/core/data/grouptokenconverter.cxx18
-rw-r--r--sc/source/core/inc/grouptokenconverter.hxx1
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;