formula/source/core/api/FormulaCompiler.cxx |    5 ++-
 sc/source/filter/excel/xetable.cxx          |   42 ++++++++++------------------
 2 files changed, 18 insertions(+), 29 deletions(-)

New commits:
commit 41cb5d7ebadb72c1abc254d21220bd118a09dbbd
Author:     Karthik Godha <[email protected]>
AuthorDate: Wed Feb 11 16:38:38 2026 +0530
Commit:     Michael Stahl <[email protected]>
CommitDate: Fri Feb 27 12:05:42 2026 +0100

    XLSX: Discard formulas with invalid external reference
    
    A formula can contain `ocExternal` token without a valid external
    reference. Discard them in OOXML export
    
    bug-document: forum-mso-en4-31562.xls
    Change-Id: I7049ad2966c8d14d12b7845b32616ad262a25f99
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199154
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit ea98a7cf6ed8c97993f60e9f8a07b09d1cc57ffc)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200404

diff --git a/formula/source/core/api/FormulaCompiler.cxx 
b/formula/source/core/api/FormulaCompiler.cxx
index d0eedc78640b..1111f1dee6af 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -2520,8 +2520,9 @@ void FormulaCompiler::CreateStringFromTokenArray( 
OUStringBuffer& rBuffer )
     while( t )
     {
         // Discard writing unknown functions without a name in OOXML ex: 
#NAME!()
-        if (t->GetOpCode() == ocNoName && t->GetType() == svByte
-            && FormulaGrammar::isOOXML(meGrammar))
+        if (FormulaGrammar::isOOXML(meGrammar)
+            && (t->GetOpCode() == ocNoName || t->GetOpCode() == ocExternal)
+            && t->GetType() == svByte)
         {
             rBuffer.setLength(0);
             rBuffer.append(GetNativeSymbol(ocErrRef));
commit 7679da69b3911b3f5727daa07b390abc0050e1fd
Author:     Karthik Godha <[email protected]>
AuthorDate: Wed Feb 11 16:30:35 2026 +0530
Commit:     Michael Stahl <[email protected]>
CommitDate: Fri Feb 27 12:05:29 2026 +0100

    XLSX: Completely discard formulas containing macros
    
    Change-Id: I8f2b034d83c14cf62f74ee3be1ed23663d5dfdad
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199153
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 108f4aa94b98ca6deffdc169068c175605d5ba67)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200403

diff --git a/sc/source/filter/excel/xetable.cxx 
b/sc/source/filter/excel/xetable.cxx
index eeccbe215c22..fc854aee1a6f 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -1016,7 +1016,8 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm )
     if (bWriteFormula)
     {
         ScTokenArray aTokenArray(*mrScFmlaCell.GetCode());
-        // If XLSX export then remove macro tokens from the array
+        bool bValid = true;
+        // Discard formulas containing macros in XLSX export.
         if (!rStrm.IsExportVBA())
         {
             formula::FormulaTokenArrayPlainIterator aIter(aTokenArray);
@@ -1025,38 +1026,25 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm 
)
             {
                 if (t->GetOpCode() == ocMacro)
                 {
-                    sal_uInt16 nStart = aIter.GetIndex() - 1;
-                    formula::FormulaToken* pNext = aIter.PeekNext();
-                    if (pNext && pNext->GetOpCode() == ocOpen)
-                    {
-                        sal_uInt16 nParenthesis = 0;
-                        do
-                        {
-                            if (pNext->GetOpCode() == ocOpen)
-                                nParenthesis++;
-                            else if (pNext->GetOpCode() == ocClose)
-                                nParenthesis--;
-
-                            aIter.Next();
-                            pNext = aIter.PeekNext();
-                        } while (nParenthesis > 0 && pNext);
-                    }
-                    aTokenArray.RemoveToken(nStart, aIter.GetIndex() - nStart);
-                    aIter.AfterRemoveToken(nStart, aIter.GetIndex() - nStart);
+                    bValid = false;
+                    break;
                 }
                 t = aIter.Next();
             }
         }
-        if (!bTagStarted)
+        if (bValid)
         {
-            rWorksheet->startElement( XML_f,
-                    XML_aca, ToPsz( (mxTokArr && mxTokArr->IsVolatile()) ||
-                        (mxAddRec && mxAddRec->IsVolatile()) ) );
+            if (!bTagStarted)
+            {
+                rWorksheet->startElement(XML_f, XML_aca,
+                                         ToPsz((mxTokArr && 
mxTokArr->IsVolatile())
+                                               || (mxAddRec && 
mxAddRec->IsVolatile())));
+            }
+            rWorksheet->writeEscaped(XclXmlUtils::ToOUString(
+                rStrm.GetRoot().GetCompileFormulaContext(), mrScFmlaCell.aPos, 
&aTokenArray,
+                mrScFmlaCell.GetErrCode()));
+            rWorksheet->endElement(XML_f);
         }
-        
rWorksheet->writeEscaped(XclXmlUtils::ToOUString(rStrm.GetRoot().GetCompileFormulaContext(),
-                                                         mrScFmlaCell.aPos, 
&aTokenArray,
-                                                         
mrScFmlaCell.GetErrCode()));
-        rWorksheet->endElement( XML_f );
     }
 
     if( strcmp( sType, "inlineStr" ) == 0 )

Reply via email to