diff options
author | Caolán McNamara <caolanm@redhat.com> | 2023-02-17 11:00:52 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2023-02-17 12:30:39 +0000 |
commit | f205403ff4efae613e87b07e7345ec20e96f68f1 (patch) | |
tree | 9cb4298c74f79f5403bca3ff3210ecee8abd8cd1 | |
parent | a07de1a335f1a25f13c992c937d21c2f16fba496 (diff) |
crashtesting: crash on export of forum-mso-en4-568138.xlsx to xls
recurses to death
warn:legacy.osl:186588:186588:sc/source/filter/excel/xeformula.cxx:518:
XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula
warn:legacy.osl:186588:186588:sc/source/filter/excel/xeformula.cxx:518:
XclExpFmlaCompImpl::CreateFormula - unknown garbage behind formula
warn:legacy.osl:186588:186588:sc/source/filter/excel/xeformula.cxx:2235:
XclExpFmlaCompImpl::PopOperandPos - token stack broken
Segmentation fault (core dumped)
Change-Id: I17172be42c9992ceb3a90c5a92344a58328dc483
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147204
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | sc/source/filter/excel/xeformula.cxx | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx index d44e13c41935..71f5056beb93 100644 --- a/sc/source/filter/excel/xeformula.cxx +++ b/sc/source/filter/excel/xeformula.cxx @@ -325,7 +325,8 @@ private: const ScAddress* pScBasePos, XclExpRefLog* pRefLog ); void RecalcTokenClasses(); - void RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass ); + void RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass, + o3tl::sorted_vector<const XclExpTokenConvInfo*>& rSeenTokens ); void FinalizeFormula(); XclTokenArrayRef CreateTokenArray(); @@ -634,7 +635,8 @@ void XclExpFmlaCompImpl::RecalcTokenClasses() XclFuncParamConv eParamConv = bNameFmla ? EXC_PARAMCONV_ARR : EXC_PARAMCONV_VAL; XclExpClassConv eClassConv = bNameFmla ? EXC_CLASSCONV_ARR : EXC_CLASSCONV_VAL; XclExpTokenConvInfo aConvInfo = { PopOperandPos(), eParamConv, !bNameFmla }; - RecalcTokenClass( aConvInfo, eParamConv, eClassConv, bNameFmla ); + o3tl::sorted_vector<const XclExpTokenConvInfo*> aSeenTokens; + RecalcTokenClass(aConvInfo, eParamConv, eClassConv, bNameFmla, aSeenTokens); } // clear operand vectors (calls to the expensive InsertZeros() may follow) @@ -643,9 +645,19 @@ void XclExpFmlaCompImpl::RecalcTokenClasses() } void XclExpFmlaCompImpl::RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, - XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass ) + XclFuncParamConv ePrevConv, XclExpClassConv ePrevClassConv, bool bWasRefClass, + o3tl::sorted_vector<const XclExpTokenConvInfo*>& rSeenTokens ) { OSL_ENSURE( rConvInfo.mnTokPos < GetSize(), "XclExpFmlaCompImpl::RecalcTokenClass - invalid token position" ); + + const bool bAlreadySeen = !rSeenTokens.insert(&rConvInfo).second; + if (bAlreadySeen) + { + SAL_WARN("sc.filter", "XclExpFmlaCompImpl::RecalcTokenClass: loop in nested operands"); + return; + } + rSeenTokens.insert(&rConvInfo); + sal_uInt8& rnTokenId = mxData->maTokVec[ rConvInfo.mnTokPos ]; sal_uInt8 nTokClass = GetTokenClass( rnTokenId ); @@ -752,7 +764,7 @@ void XclExpFmlaCompImpl::RecalcTokenClass( const XclExpTokenConvInfo& rConvInfo, if( rConvInfo.mnTokPos < mxData->maOpListVec.size() ) if( const XclExpOperandList* pOperands = mxData->maOpListVec[ rConvInfo.mnTokPos ].get() ) for( const auto& rOperand : *pOperands ) - RecalcTokenClass( rOperand, eConv, eClassConv, nTokClass == EXC_TOKCLASS_REF ); + RecalcTokenClass( rOperand, eConv, eClassConv, nTokClass == EXC_TOKCLASS_REF, rSeenTokens ); } void XclExpFmlaCompImpl::FinalizeFormula() |