summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-05-01 12:16:12 -0400
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-05-01 12:17:45 -0400
commit7fbe0f56192f7e106c560646d37fbb93b69b0446 (patch)
tree2a4dec15c4ba3f69a1a7a757386135a6d921112c /sc/source
parent6b431b1f0d397067504b5300d49e10e232936836 (diff)
fdo#77806: Use the common block position set for start and end listening.
Else an invalid iterator may result, which would eventually leads to a crash. Change-Id: Ie909de61244d661c72a3450cc69b29fbb218a248
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/column.cxx9
-rw-r--r--sc/source/core/data/listenercontext.cxx9
-rw-r--r--sc/source/core/tool/token.cxx8
3 files changed, 22 insertions, 4 deletions
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 208c04688e53..a76e746adc89 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2176,9 +2176,14 @@ class UpdateRefOnNonCopy : std::unary_function<sc::FormulaGroupEntry, void>
// Perform end-listening, start-listening, and dirtying on all
// formula cells in the group.
- sc::StartListeningContext aStartCxt(mpCxt->mrDoc);
+ // Make sure that the start and end listening contexts share the
+ // same block position set, else an invalid iterator may ensue.
+ boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(
+ new sc::ColumnBlockPositionSet(mpCxt->mrDoc));
+
+ sc::StartListeningContext aStartCxt(mpCxt->mrDoc, pPosSet);
+ sc::EndListeningContext aEndCxt(mpCxt->mrDoc, pPosSet, pOldCode.get());
- sc::EndListeningContext aEndCxt(mpCxt->mrDoc, pOldCode.get());
aEndCxt.setPositionDelta(
ScAddress(-mpCxt->mnColDelta, -mpCxt->mnRowDelta, -mpCxt->mnTabDelta));
diff --git a/sc/source/core/data/listenercontext.cxx b/sc/source/core/data/listenercontext.cxx
index add75a25a0e7..dcdffac65710 100644
--- a/sc/source/core/data/listenercontext.cxx
+++ b/sc/source/core/data/listenercontext.cxx
@@ -16,6 +16,10 @@ namespace sc {
StartListeningContext::StartListeningContext(ScDocument& rDoc) :
mrDoc(rDoc), mpSet(new ColumnBlockPositionSet(rDoc)) {}
+StartListeningContext::StartListeningContext(
+ ScDocument& rDoc, const boost::shared_ptr<ColumnBlockPositionSet>& pSet) :
+ mrDoc(rDoc), mpSet(pSet) {}
+
ScDocument& StartListeningContext::getDoc()
{
return mrDoc;
@@ -30,6 +34,11 @@ EndListeningContext::EndListeningContext(ScDocument& rDoc, ScTokenArray* pOldCod
mrDoc(rDoc), maSet(false), mpPosSet(new ColumnBlockPositionSet(rDoc)),
mpOldCode(pOldCode), maPosDelta(0,0,0) {}
+EndListeningContext::EndListeningContext(
+ ScDocument& rDoc, const boost::shared_ptr<ColumnBlockPositionSet>& pSet, ScTokenArray* pOldCode) :
+ mrDoc(rDoc), maSet(false), mpPosSet(pSet),
+ mpOldCode(pOldCode), maPosDelta(0,0,0) {}
+
void EndListeningContext::setPositionDelta( const ScAddress& rDelta )
{
maPosDelta = rDelta;
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index bd884eb0246c..b1f8e022eade 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2785,13 +2785,17 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove(
const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos, const ScAddress& rNewPos )
{
+ sc::RefUpdateResult aRes;
+
+ if (!rCxt.mnColDelta && !rCxt.mnRowDelta && !rCxt.mnTabDelta)
+ // The cell hasn't moved at all.
+ return aRes;
+
// When moving, the range is the destination range. We need to use the old
// range prior to the move for hit analysis.
ScRange aOldRange = rCxt.maRange;
aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
- sc::RefUpdateResult aRes;
-
FormulaToken** p = pCode;
FormulaToken** pEnd = p + static_cast<size_t>(nLen);
for (; p != pEnd; ++p)