summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2023-02-17 11:00:52 +0000
committerCaolán McNamara <caolanm@redhat.com>2023-02-17 12:30:39 +0000
commitf205403ff4efae613e87b07e7345ec20e96f68f1 (patch)
tree9cb4298c74f79f5403bca3ff3210ecee8abd8cd1
parenta07de1a335f1a25f13c992c937d21c2f16fba496 (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.cxx20
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()