summaryrefslogtreecommitdiffstats
path: root/sc
diff options
context:
space:
mode:
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/document.hxx5
-rw-r--r--sc/inc/documentimport.hxx2
-rw-r--r--sc/inc/mtvelements.hxx1
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/qa/extras/scpdfexport.cxx16
-rw-r--r--sc/qa/extras/testdocuments/forcepoint97.xlsxbin0 -> 21127 bytes
-rw-r--r--sc/qa/unit/data/xlsx/forcepoint107.xlsxbin0 -> 398436 bytes
-rw-r--r--sc/qa/unit/filters-test.cxx9
-rw-r--r--sc/source/core/data/colorscale.cxx6
-rw-r--r--sc/source/core/data/documen2.cxx1
-rw-r--r--sc/source/core/data/document.cxx9
-rw-r--r--sc/source/core/data/documentimport.cxx22
-rw-r--r--sc/source/core/data/dpobject.cxx11
-rw-r--r--sc/source/core/data/dptabres.cxx12
-rw-r--r--sc/source/core/data/formulacell.cxx6
-rw-r--r--sc/source/core/data/mtvelements.cxx5
-rw-r--r--sc/source/core/data/table2.cxx17
-rw-r--r--sc/source/core/data/table3.cxx4
-rw-r--r--sc/source/core/inc/interpre.hxx12
-rw-r--r--sc/source/core/tool/interpr1.cxx4
-rw-r--r--sc/source/core/tool/interpr4.cxx14
-rw-r--r--sc/source/core/tool/interpr7.cxx3
-rw-r--r--sc/source/filter/lotus/op.cxx11
-rw-r--r--sc/source/filter/oox/sheetdatabuffer.cxx13
-rw-r--r--sc/source/filter/xml/XMLCalculationSettingsContext.cxx14
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx26
-rw-r--r--sc/source/ui/docshell/docsh4.cxx8
-rw-r--r--sc/source/ui/unoobj/chart2uno.cxx3
-rw-r--r--sc/source/ui/view/output2.cxx7
29 files changed, 200 insertions, 43 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index dff46dffd699..a5b9c8fbe781 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -541,6 +541,8 @@ private:
bool mbTrackFormulasPending : 1;
bool mbFinalTrackFormulas : 1;
+ // This indicates if a ScOutputData::LayoutStrings() is in progress.
+ bool mbLayoutStrings : 1;
size_t mnMutationGuardFlags;
@@ -2429,6 +2431,9 @@ public:
SC_DLLPUBLIC ScColumnsRange GetColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const;
+ bool IsInLayoutStrings() const { return mbLayoutStrings; }
+ void SetLayoutStrings(bool bSet) { mbLayoutStrings = bSet; }
+
private:
/**
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index 1a8b1cbd514f..7e5be71c8339 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -123,6 +123,8 @@ public:
void setMergedCells(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
+ void invalidateBlockPositionSet(SCTAB nTab);
+
void finalize();
/** Broadcast all formula cells that are marked with
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index f13562d47fbd..e441e0473558 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -169,6 +169,7 @@ public:
~TableColumnBlockPositionSet();
ColumnBlockPosition* getBlockPosition( SCCOL nCol );
+ void invalidate(); // discards cached positions
};
ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index dae1f6f36eaf..e4a9d79ff86c 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -464,6 +464,8 @@ public:
void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
ScPostIt* ReleaseNote( SCCOL nCol, SCROW nRow );
+ ScPostIt* GetNote( SCCOL nCol, SCROW nRow );
+ void SetNote( SCCOL nCol, SCROW nRow, ScPostIt* pNote );
size_t GetNoteCount( SCCOL nCol ) const;
SCROW GetNotePosition( SCCOL nCol, size_t nIndex ) const;
diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx
index 02f00f8fac5d..69bcbde242d6 100644
--- a/sc/qa/extras/scpdfexport.cxx
+++ b/sc/qa/extras/scpdfexport.cxx
@@ -55,12 +55,16 @@ private:
// unit tests
public:
void testExportRange_Tdf120161();
+ void testForcepoint97();
CPPUNIT_TEST_SUITE(ScPDFExportTest);
CPPUNIT_TEST(testExportRange_Tdf120161);
+ CPPUNIT_TEST(testForcepoint97);
CPPUNIT_TEST_SUITE_END();
};
+char const DATA_DIRECTORY[] = "/sc/qa/extras/testdocuments/";
+
void ScPDFExportTest::setUp()
{
test::BootstrapFixture::setUp();
@@ -278,6 +282,18 @@ void ScPDFExportTest::testExportRange_Tdf120161()
}
}
+// just needs to not crash on export to pdf
+void ScPDFExportTest::testForcepoint97()
+{
+ mxComponent = loadFromDesktop(m_directories.getURLFromSrc(DATA_DIRECTORY) + "forcepoint97.xlsx",
+ "com.sun.star.sheet.SpreadsheetDocument");
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+
+ // A1:H81
+ ScRange range1(0, 0, 0, 7, 81, 0);
+ std::shared_ptr<utl::TempFile> pPDFFile = exportToPdf(xModel, range1);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(ScPDFExportTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/qa/extras/testdocuments/forcepoint97.xlsx b/sc/qa/extras/testdocuments/forcepoint97.xlsx
new file mode 100644
index 000000000000..152fbbc45a9f
--- /dev/null
+++ b/sc/qa/extras/testdocuments/forcepoint97.xlsx
Binary files differ
diff --git a/sc/qa/unit/data/xlsx/forcepoint107.xlsx b/sc/qa/unit/data/xlsx/forcepoint107.xlsx
new file mode 100644
index 000000000000..f5238dcb5c3e
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/forcepoint107.xlsx
Binary files differ
diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx
index 2a0afb4323aa..48b60471fc8e 100644
--- a/sc/qa/unit/filters-test.cxx
+++ b/sc/qa/unit/filters-test.cxx
@@ -85,6 +85,7 @@ public:
void testSortWithSheetExternalReferencesODS();
void testSortWithSheetExternalReferencesODS_Impl( ScDocShellRef const & xDocShRef, SCROW nRow1, SCROW nRow2,
bool bCheckRelativeInSheet );
+ void testForcepoint107();
CPPUNIT_TEST_SUITE(ScFiltersTest);
CPPUNIT_TEST(testCVEs);
@@ -106,6 +107,7 @@ public:
CPPUNIT_TEST(testEnhancedProtectionXLSX);
CPPUNIT_TEST(testSortWithSharedFormulasODS);
CPPUNIT_TEST(testSortWithSheetExternalReferencesODS);
+ CPPUNIT_TEST(testForcepoint107);
CPPUNIT_TEST_SUITE_END();
@@ -761,6 +763,13 @@ void ScFiltersTest::testSortWithSheetExternalReferencesODS_Impl( ScDocShellRef c
}
}
+// just needs to not crash on recalc
+void ScFiltersTest::testForcepoint107()
+{
+ ScDocShellRef xDocSh = loadDoc(u"forcepoint107.", FORMAT_XLSX, true);
+ xDocSh->DoHardRecalc();
+}
+
ScFiltersTest::ScFiltersTest()
: ScBootstrapFixture( "sc/qa/unit/data" )
, mbUpdateReferenceOnSort(false)
diff --git a/sc/source/core/data/colorscale.cxx b/sc/source/core/data/colorscale.cxx
index 4ea3606e48b8..a257fae0a87d 100644
--- a/sc/source/core/data/colorscale.cxx
+++ b/sc/source/core/data/colorscale.cxx
@@ -484,8 +484,10 @@ Color CalcColor( double nVal, double nVal1, const Color& rCol1, double nVal2, co
double GetPercentile( const std::vector<double>& rArray, double fPercentile )
{
size_t nSize = rArray.size();
- size_t nIndex = static_cast<size_t>(::rtl::math::approxFloor( fPercentile * (nSize-1)));
- double fDiff = fPercentile * (nSize-1) - ::rtl::math::approxFloor( fPercentile * (nSize-1));
+ double fFloor = ::rtl::math::approxFloor(fPercentile * (nSize-1));
+ SAL_WARN_IF(fFloor < 0, "sc", "negative percentile");
+ size_t nIndex = fFloor >= 0 ? static_cast<size_t>(fFloor) : 0;
+ double fDiff = fPercentile * (nSize-1) - fFloor;
std::vector<double>::const_iterator iter = rArray.begin() + nIndex;
if (fDiff == 0.0)
return *iter;
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 88c9b972c912..a810494b056c 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -221,6 +221,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
mbUseEmbedFonts(false),
mbTrackFormulasPending(false),
mbFinalTrackFormulas(false),
+ mbLayoutStrings(false),
mnMutationGuardFlags(0)
{
SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 06a1a532e628..ea10ba0913f3 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6448,7 +6448,7 @@ ScPostIt* ScDocument::GetNote(const ScAddress& rPos)
ScPostIt* ScDocument::GetNote(SCCOL nCol, SCROW nRow, SCTAB nTab)
{
if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
- return maTabs[nTab]->aCol[nCol].GetCellNote(nRow);
+ return maTabs[nTab]->GetNote(nCol, nRow);
else
return nullptr;
@@ -6461,7 +6461,8 @@ void ScDocument::SetNote(const ScAddress& rPos, ScPostIt* pNote)
void ScDocument::SetNote(SCCOL nCol, SCROW nRow, SCTAB nTab, ScPostIt* pNote)
{
- return maTabs[nTab]->aCol[nCol].SetCellNote(nRow, pNote);
+ if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
+ maTabs[nTab]->SetNote(nCol, nRow, std::move(pNote));
}
bool ScDocument::HasNote(const ScAddress& rPos) const
@@ -6491,6 +6492,9 @@ bool ScDocument::HasColNotes(SCCOL nCol, SCTAB nTab) const
if (!pTab)
return false;
+ if (nCol >= MAXCOLCOUNT)
+ return false;
+
return pTab->aCol[nCol].HasCellNotes();
}
@@ -6534,6 +6538,7 @@ ScPostIt* ScDocument::GetOrCreateNote(const ScAddress& rPos)
else
return CreateNote(rPos);
}
+
ScPostIt* ScDocument::CreateNote(const ScAddress& rPos)
{
ScPostIt* pPostIt = new ScPostIt(*this, rPos);
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index a7a3ba8e0326..04aa11c9b4b7 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -93,6 +93,15 @@ struct ScDocumentImportImpl
return rTab.getBlockPosition(nCol);
}
+ void invalidateBlockPositionSet(SCTAB nTab)
+ {
+ if (sal_uInt16(nTab) >= maBlockPosSet.size())
+ return;
+
+ sc::TableColumnBlockPositionSet& rTab = maBlockPosSet[nTab];
+ rTab.invalidate();
+ }
+
void initForSheets()
{
size_t n = mrDoc.GetTableCount();
@@ -180,6 +189,11 @@ void ScDocumentImport::setOriginDate(sal_uInt16 nYear, sal_uInt16 nMonth, sal_uI
mpImpl->mrDoc.pDocOptions->SetDate(nDay, nMonth, nYear);
}
+void ScDocumentImport::invalidateBlockPositionSet(SCTAB nTab)
+{
+ mpImpl->invalidateBlockPositionSet(nTab);
+}
+
void ScDocumentImport::setAutoInput(const ScAddress& rPos, const OUString& rStr, const ScSetStringParam* pStringParam)
{
ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
@@ -367,6 +381,14 @@ void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCel
mpImpl->mrDoc.CheckLinkFormulaNeedingCheck( *pCell->GetCode());
sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+
+ sc::CellStoreType::position_type aPos = rCells.position(rPos.Row());
+ if (aPos.first != rCells.end() && aPos.first->type == sc::element_type_formula)
+ {
+ ScFormulaCell* p = sc::formula_block::at(*aPos.first->data, aPos.second);
+ sc::SharedFormulaUtil::unshareFormulaCell(aPos, *p);
+ }
+
pBlockPos->miCellPos =
rCells.set(pBlockPos->miCellPos, rPos.Row(), pCell);
}
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index cb733d25a8da..22d1941f1eb0 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -1038,7 +1038,16 @@ bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelDa
for (sal_Int32 i = 0; i < nCount; ++i)
{
- Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY);
+ Reference<container::XNamed> xMember;
+ try
+ {
+ xMember = Reference<container::XNamed>(xMembersIA->getByIndex(i), UNO_QUERY);
+ }
+ catch (const container::NoSuchElementException&)
+ {
+ //TOOLS_WARN_EXCEPTION("sc", "ScNameToIndexAccess getByIndex failed");
+ }
+
ScDPLabelData::Member aMem;
if (xMember.is())
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index 38107b70e09f..d3e0d108f38a 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -2769,7 +2769,10 @@ ScDPResultDimension::~ScDPResultDimension()
ScDPResultMember *ScDPResultDimension::FindMember( SCROW iData ) const
{
if( bIsDataLayout )
- return maMemberArray[0].get();
+ {
+ SAL_WARN_IF(maMemberArray.empty(), "sc.core", "MemberArray is empty");
+ return !maMemberArray.empty() ? maMemberArray[0].get() : nullptr;
+ }
MemberHash::const_iterator aRes = maMemberHash.find( iData );
if( aRes != maMemberHash.end()) {
@@ -2976,8 +2979,11 @@ void ScDPResultDimension::LateInitFrom(
long ScDPResultDimension::GetSize(long nMeasure) const
{
- long nTotal = 0;
long nMemberCount = maMemberArray.size();
+ if (!nMemberCount)
+ return 0;
+
+ long nTotal = 0;
if (bIsDataLayout)
{
OSL_ENSURE(nMeasure == SC_DPMEASURE_ALL || pResultData->GetMeasureCount() == 1,
@@ -3130,7 +3136,7 @@ void ScDPResultDimension::SortMembers( ScDPResultMember* pRefMember )
// handle children
// for data layout, call only once - sorting measure is always taken from settings
- long nLoopCount = bIsDataLayout ? 1 : nCount;
+ long nLoopCount = bIsDataLayout ? std::min<long>(1, nCount) : nCount;
for (long i=0; i<nLoopCount; i++)
{
ScDPResultMember* pMember = maMemberArray[i].get();
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index b43e908352ed..77b6746a7fcb 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -939,6 +939,9 @@ ScFormulaCell::~ScFormulaCell()
if (!mxGroup || !mxGroup->mpCode)
// Formula token is not shared.
delete pCode;
+
+ if (mxGroup && mxGroup->mpTopCell == this)
+ mxGroup->mpTopCell = nullptr;
}
ScFormulaCell* ScFormulaCell::Clone() const
@@ -2010,7 +2013,8 @@ void ScFormulaCell::InterpretTail( ScInterpreterContext& rContext, ScInterpretTa
// XXX if mbNeedsNumberFormat was set even if the current format
// was not General then we'd have to obtain the current format here
// and check at least the types.
- if (bSetFormat && (bForceNumberFormat || ((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0)))
+ const bool bSetNumberFormat = bSetFormat && (bForceNumberFormat || ((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0));
+ if (bSetNumberFormat && !pDocument->IsInLayoutStrings())
{
// set number format explicitly
if (!pDocument->IsThreadedGroupCalcInProgress())
diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx
index e34010af54d8..598b43f963f3 100644
--- a/sc/source/core/data/mtvelements.cxx
+++ b/sc/source/core/data/mtvelements.cxx
@@ -153,6 +153,11 @@ ColumnBlockPosition* TableColumnBlockPositionSet::getBlockPosition( SCCOL nCol )
return &it->second;
}
+void TableColumnBlockPositionSet::invalidate()
+{
+ mpImpl->maColumns.clear();
+}
+
ScRefCellValue toRefCell( const sc::CellStoreType::const_iterator& itPos, size_t nOffset )
{
switch (itPos->type)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index e640b31622f4..66c072d12cc0 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1600,6 +1600,21 @@ ScPostIt* ScTable::ReleaseNote( SCCOL nCol, SCROW nRow )
return aCol[nCol].ReleaseNote(nRow);
}
+ScPostIt* ScTable::GetNote( SCCOL nCol, SCROW nRow )
+{
+ if (!ValidCol(nCol) || nCol >= MAXCOLCOUNT)
+ return nullptr;
+ return aCol[nCol].GetCellNote(nRow);
+}
+
+void ScTable::SetNote( SCCOL nCol, SCROW nRow, ScPostIt* pNote )
+{
+ if (!ValidColRow(nCol, nRow))
+ return;
+
+ CreateColumnIfNotExists(nCol).SetCellNote(nRow, std::move(pNote));
+}
+
size_t ScTable::GetNoteCount( SCCOL nCol ) const
{
if (!ValidCol(nCol))
@@ -3714,7 +3729,7 @@ void ScTable::CopyData( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW n
if (bThisTab)
{
- aCell.release(aCol[nDestX], nDestY);
+ aCell.release(CreateColumnIfNotExists(nDestX), nDestY);
SetPattern( nDestX, nDestY, *GetPattern( nCol, nRow ) );
}
else
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 487e7eec6626..0b78cd9c31f4 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -3145,6 +3145,10 @@ SCSIZE ScTable::Query(const ScQueryParam& rParamOrg, bool bKeepSub)
if (bResult)
{
CopyData( aParam.nCol1,j, aParam.nCol2,j, aParam.nDestCol,nOutRow,aParam.nDestTab );
+#if 0
+ if( nTab == aParam.nDestTab ) // copy to self, changes may invalidate caching position hints
+ blockPos.invalidate();
+#endif
++nOutRow;
}
}
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index e7d7f5e2aff8..b4fcbd9698eb 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -237,6 +237,7 @@ private:
inline bool MustHaveParamCount( short nAct, short nMust );
inline bool MustHaveParamCount( short nAct, short nMust, short nMax );
inline bool MustHaveParamCountMin( short nAct, short nMin );
+ inline bool MustHaveParamCountMinWithStackCheck( short nAct, short nMin );
void PushParameterExpected();
void PushIllegalParameter();
void PushIllegalArgument();
@@ -1064,6 +1065,17 @@ inline bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin )
return false;
}
+inline bool ScInterpreter::MustHaveParamCountMinWithStackCheck( short nAct, short nMin )
+{
+ assert(sp >= nAct);
+ if (sp < nAct)
+ {
+ PushParameterExpected();
+ return false;
+ }
+ return MustHaveParamCountMin( nAct, nMin);
+}
+
inline bool ScInterpreter::CheckStringPositionArgument( double & fVal )
{
if (!rtl::math::isFinite( fVal))
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 2f7502073b46..2fcb409a5307 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -7384,7 +7384,7 @@ void ScInterpreter::ScVLookup()
void ScInterpreter::ScSubTotal()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCountMin( nParamCount, 2 ) )
+ if ( MustHaveParamCountMinWithStackCheck( nParamCount, 2 ) )
{
// We must fish the 1st parameter deep from the stack! And push it on top.
const FormulaToken* p = pStack[ sp - nParamCount ];
@@ -7431,7 +7431,7 @@ void ScInterpreter::ScSubTotal()
void ScInterpreter::ScAggregate()
{
sal_uInt8 nParamCount = GetByte();
- if ( MustHaveParamCountMin( nParamCount, 3 ) )
+ if ( MustHaveParamCountMinWithStackCheck( nParamCount, 3 ) )
{
// fish the 1st parameter from the stack and push it on top.
const FormulaToken* p = pStack[ sp - nParamCount ];
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 32238916e162..d234ed16d896 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -4029,11 +4029,19 @@ StackVar ScInterpreter::Interpret()
eOp = ocNone; // JumpMatrix created
nStackBase = sp;
}
- else
+ else if (sp >= pCur->GetParamCount())
nStackBase = sp - pCur->GetParamCount();
+ else
+ {
+ SAL_WARN("sc.core", "Stack anomaly at " << aPos.Format(
+ ScRefFlags::VALID | ScRefFlags::FORCE_DOC | ScRefFlags::TAB_3D, pDok)
+ << " eOp: " << static_cast<int>(eOp)
+ << " params: " << static_cast<int>(pCur->GetParamCount())
+ << " nStackBase: " << nStackBase << " sp: " << sp);
+ nStackBase = sp;
+ assert(!"underflow");
+ }
}
- if ( nStackBase > sp )
- nStackBase = sp; // underflow?!?
switch( eOp )
{
diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx
index 7b11e6faddab..56f6b2b3e6d4 100644
--- a/sc/source/core/tool/interpr7.cxx
+++ b/sc/source/core/tool/interpr7.cxx
@@ -220,6 +220,7 @@ void ScInterpreter::ScFilterXML()
case XPATH_STRING:
PushString(OUString::createFromAscii(reinterpret_cast<char*>(pXPathObj->stringval)));
break;
+#if LIBXML_VERSION < 21000 || defined(LIBXML_XPTR_LOCS_ENABLED)
case XPATH_POINT:
PushNoValue();
break;
@@ -229,13 +230,13 @@ void ScInterpreter::ScFilterXML()
case XPATH_LOCATIONSET:
PushNoValue();
break;
+#endif
case XPATH_USERS:
PushNoValue();
break;
case XPATH_XSLT_TREE:
PushNoValue();
break;
-
}
}
}
diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx
index 7dec5cfbd0d1..d2510ff5d1ab 100644
--- a/sc/source/filter/lotus/op.cxx
+++ b/sc/source/filter/lotus/op.cxx
@@ -580,14 +580,9 @@ void OP_SheetName123(LotusContext& rContext, SvStream& rStream, sal_uInt16 nLeng
SCTAB nSheetNum = static_cast<SCTAB>(nDummy);
rContext.pDoc->MakeTable(nSheetNum);
- ::std::vector<sal_Char> sSheetName;
- sSheetName.reserve(nLength-4);
- for (sal_uInt16 i = 4; i < nLength; ++i)
- {
- sal_Char c;
- rStream.ReadChar( c );
- sSheetName.push_back(c);
- }
+ const size_t nStrLen = nLength - 4;
+ std::vector<sal_Char> sSheetName(nStrLen + 1);
+ sSheetName[rStream.ReadBytes(sSheetName.data(), nStrLen)] = 0;
if (!sSheetName.empty())
{
diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx
index cf44072cd9e3..ccca237964f7 100644
--- a/sc/source/filter/oox/sheetdatabuffer.cxx
+++ b/sc/source/filter/oox/sheetdatabuffer.cxx
@@ -402,10 +402,23 @@ void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const
void SheetDataBuffer::finalizeImport()
{
+ ScDocumentImport& rDocImport = getDocImport();
+
+ SCTAB nStartTabInvalidatedIters(SCTAB_MAX);
+ SCTAB nEndTabInvalidatedIters(0);
+
// create all array formulas
for( ArrayFormulaVector::iterator aIt = maArrayFormulas.begin(), aEnd = maArrayFormulas.end(); aIt != aEnd; ++aIt )
+ {
finalizeArrayFormula( aIt->first, aIt->second );
+ nStartTabInvalidatedIters = std::min(aIt->first.aStart.Tab(), nStartTabInvalidatedIters);
+ nEndTabInvalidatedIters = std::max(aIt->first.aEnd.Tab(), nEndTabInvalidatedIters);
+ }
+
+ for (SCTAB nTab = nStartTabInvalidatedIters; nTab <= nEndTabInvalidatedIters; ++nTab)
+ rDocImport.invalidateBlockPositionSet(nTab);
+
// create all table operations
for( TableOperationVector::iterator aIt = maTableOperations.begin(), aEnd = maTableOperations.end(); aIt != aEnd; ++aIt )
finalizeTableOperation( aIt->first, aIt->second );
diff --git a/sc/source/filter/xml/XMLCalculationSettingsContext.cxx b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx
index fd7aab6ddb23..802cbf35a00c 100644
--- a/sc/source/filter/xml/XMLCalculationSettingsContext.cxx
+++ b/sc/source/filter/xml/XMLCalculationSettingsContext.cxx
@@ -150,12 +150,14 @@ ScXMLNullDateContext::ScXMLNullDateContext( ScXMLImport& rImport,
if (aIter != rAttrList->end())
{
util::DateTime aDateTime;
- ::sax::Converter::parseDateTime(aDateTime, aIter.toString());
- util::Date aDate;
- aDate.Day = aDateTime.Day;
- aDate.Month = aDateTime.Month;
- aDate.Year = aDateTime.Year;
- pCalcSet->SetNullDate(aDate);
+ if (::sax::Converter::parseDateTime(aDateTime, aIter.toString()))
+ {
+ util::Date aDate;
+ aDate.Day = aDateTime.Day;
+ aDate.Month = aDateTime.Month;
+ aDate.Year = aDateTime.Year;
+ pCalcSet->SetNullDate(aDate);
+ }
}
}
}
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 8cd6ebc11085..b189f4f67762 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -108,6 +108,7 @@
#include <tools/color.hxx>
#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
#include <rtl/math.hxx>
#include <svl/zforlist.hxx>
#include <svx/unoshape.hxx>
@@ -3453,16 +3454,23 @@ void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape,
uno::Sequence< OUString > aRepresentations(
xReceiver->getUsedRangeRepresentations());
SvXMLAttributeList* pAttrList = nullptr;
- if(aRepresentations.getLength())
+ try
{
- // add the ranges used by the chart to the shape
- // element to be able to start listening after
- // load (when the chart is not yet loaded)
- uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY );
- sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter );
- pAttrList = new SvXMLAttributeList();
- pAttrList->AddAttribute(
- GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
+ if (aRepresentations.getLength())
+ {
+ // add the ranges used by the chart to the shape
+ // element to be able to start listening after
+ // load (when the chart is not yet loaded)
+ uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY );
+ sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter );
+ pAttrList = new SvXMLAttributeList();
+ pAttrList->AddAttribute(
+ GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges );
+ }
+ }
+ catch (const lang::IllegalArgumentException&)
+ {
+ //TOOLS_WARN_EXCEPTION("sc", "Exception in lcl_RangeSequenceToString - invalid range?");
}
GetShapeExport()->exportShape(xShape, XMLShapeExportFlags::NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList);
}
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 52a44126539d..916cd1aa1b30 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1108,10 +1108,10 @@ void ScDocShell::Execute( SfxRequest& rReq )
EnableSharedSettings( false );
- if ( pBindings )
- {
- pBindings->ExecuteSynchron( SID_SAVEDOC );
- }
+ // Do *not* use dispatch mechanism in this place - we don't want others (extensions etc.) to intercept this.
+ uno::Reference<frame::XStorable> xStorable2(
+ GetModel(), uno::UNO_QUERY_THROW);
+ xStorable2->store();
ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
if ( pTabView )
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 89ebe89061ee..e019dbb6dfa1 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -2206,7 +2206,10 @@ OUString SAL_CALL ScChart2DataProvider::convertRangeToXML( const OUString& sRang
ScRefTokenHelper::compileRangeRepresentation(
aRefTokens, sRangeRepresentation, m_pDocument, cSep, m_pDocument->GetGrammar(), true);
if (aRefTokens.empty())
+ {
+ SAL_WARN("sc", "convertRangeToXML throw IllegalArgumentException from input of: " << sRangeRepresentation);
throw lang::IllegalArgumentException();
+ }
Tokens2RangeStringXML converter(m_pDocument);
converter = ::std::for_each(aRefTokens.begin(), aRefTokens.end(), converter);
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 3dfaaa9889f9..a956be4a7205 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -74,6 +74,7 @@
#include <scopetools.hxx>
#include <com/sun/star/i18n/DirectionProperty.hpp>
+#include <comphelper/scopeguard.hxx>
#include <comphelper/string.hxx>
#include <memory>
@@ -1453,6 +1454,12 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
tools::Rectangle ScOutputData::LayoutStrings(bool bPixelToLogic, bool bPaint, const ScAddress &rAddress)
{
+ bool bOrigIsInLayoutStrings = mpDoc->IsInLayoutStrings();
+ mpDoc->SetLayoutStrings(true);
+ comphelper::ScopeGuard g([this, bOrigIsInLayoutStrings] {
+ mpDoc->SetLayoutStrings(bOrigIsInLayoutStrings);
+ });
+
OSL_ENSURE( mpDev == mpRefDevice ||
mpDev->GetMapMode().GetMapUnit() == mpRefDevice->GetMapMode().GetMapUnit(),
"LayoutStrings: different MapUnits ?!?!" );