sc/source/filter/excel/xeformula.cxx |   20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

New commits:
commit f205403ff4efae613e87b07e7345ec20e96f68f1
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Feb 17 11:00:52 2023 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Feb 17 12:30:39 2023 +0000

    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 <caol...@redhat.com>

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()

Reply via email to