diff options
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/document.hxx | 5 | ||||
-rw-r--r-- | sc/qa/extras/scpdfexport.cxx | 16 | ||||
-rw-r--r-- | sc/qa/extras/testdocuments/forcepoint97.xlsx | bin | 0 -> 21127 bytes | |||
-rw-r--r-- | sc/qa/unit/data/xlsx/forcepoint107.xlsx | bin | 0 -> 398436 bytes | |||
-rw-r--r-- | sc/qa/unit/filters-test.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/data/colorscale.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/documentimport.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/dptabres.cxx | 12 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 12 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/tool/interpr7.cxx | 3 | ||||
-rw-r--r-- | sc/source/filter/xml/XMLCalculationSettingsContext.cxx | 14 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlexprt.cxx | 26 | ||||
-rw-r--r-- | sc/source/ui/unoobj/chart2uno.cxx | 3 | ||||
-rw-r--r-- | sc/source/ui/view/output2.cxx | 7 |
19 files changed, 129 insertions, 28 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/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 Binary files differnew file mode 100644 index 000000000000..152fbbc45a9f --- /dev/null +++ b/sc/qa/extras/testdocuments/forcepoint97.xlsx diff --git a/sc/qa/unit/data/xlsx/forcepoint107.xlsx b/sc/qa/unit/data/xlsx/forcepoint107.xlsx Binary files differnew file mode 100644 index 000000000000..f5238dcb5c3e --- /dev/null +++ b/sc/qa/unit/data/xlsx/forcepoint107.xlsx 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/documentimport.cxx b/sc/source/core/data/documentimport.cxx index 079a752d55c7..04aa11c9b4b7 100644 --- a/sc/source/core/data/documentimport.cxx +++ b/sc/source/core/data/documentimport.cxx @@ -381,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/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/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/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 ?!?!" ); |