This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a commit to branch openformula
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit c020ef0fc7321930cc675bc23275eff9973adda8
Author: Jim Jagielski <[email protected]>
AuthorDate: Fri Nov 13 08:47:34 2026 -0500

    Raise the formula limit from 512 to 2048 tokens and refuse longer ones at 
input
    
    ODF 1.4 asks for formulas of at least 1024 characters.
    
    Longer formulas loaded from a file keep their text instead
    of being saved shorter, and more than 255 arguments is an error rather
    than a count that wraps.
---
 main/formula/inc/formula/FormulaCompiler.hxx     |  2 +-
 main/formula/source/core/api/FormulaCompiler.cxx |  5 ++++-
 main/formula/source/core/api/token.cxx           |  4 ++++
 main/sc/inc/compiler.hxx                         |  2 +-
 main/sc/source/core/inc/interpre.hxx             |  2 +-
 main/sc/source/core/tool/compiler.cxx            |  8 ++++++++
 main/sc/source/core/tool/interpr4.cxx            |  5 +++++
 main/sc/source/ui/view/viewfunc.cxx              | 18 ++++++++++++++++++
 8 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/main/formula/inc/formula/FormulaCompiler.hxx 
b/main/formula/inc/formula/FormulaCompiler.hxx
index 64673788bc..008669e791 100644
--- a/main/formula/inc/formula/FormulaCompiler.hxx
+++ b/main/formula/inc/formula/FormulaCompiler.hxx
@@ -41,7 +41,7 @@
 
 
 #define MAXJUMPCOUNT 32     /* maximum number of jumps (ocChose) */
-#define MAXCODE      512    /* maximum number of tokens in formula */
+#define MAXCODE      2048   /* maximum number of tokens in formula */
 
 
 namespace com { namespace sun { namespace star {
diff --git a/main/formula/source/core/api/FormulaCompiler.cxx 
b/main/formula/source/core/api/FormulaCompiler.cxx
index df8ac404e5..d233ccd36c 100644
--- a/main/formula/source/core/api/FormulaCompiler.cxx
+++ b/main/formula/source/core/api/FormulaCompiler.cxx
@@ -1050,7 +1050,10 @@ void FormulaCompiler::Factor()
                 nSepCount++;
                 while ( (eOp == ocSep) && (!pArr->GetCodeError() || 
bIgnoreErrors) )
                 {
-                    nSepCount++;
+                    if ( nSepCount == 255 )
+                        SetError( errCodeOverflow );    // the count is kept 
in a byte
+                    else
+                        nSepCount++;
                     NextToken();
                     eOp = Expression();
                 }
diff --git a/main/formula/source/core/api/token.cxx 
b/main/formula/source/core/api/token.cxx
index fee11f9f25..3184f7f526 100644
--- a/main/formula/source/core/api/token.cxx
+++ b/main/formula/source/core/api/token.cxx
@@ -38,6 +38,7 @@
 #include "formula/token.hxx"
 #include "formula/tokenarray.hxx"
 #include "formula/FormulaCompiler.hxx"
+#include "formula/errorcodes.hxx"
 #include <formula/compiler.hrc>
 //#include "rechead.hxx"
 //#include "parclass.hxx"
@@ -323,6 +324,9 @@ bool FormulaTokenArray::Fill(const uno::Sequence< 
sheet::FormulaToken >& _aSeque
     {
         bError |= AddFormulaToken( _aSequence[nPos] ,_pRef);
     }
+    // Add() drops what does not fit; without an error the shorter formula 
would be calculated
+    if ( nLen >= MAXCODE )
+        SetCodeError( errCodeOverflow );
     return bError;
 }
 //////////////////////////////////////////////////////////////////////////
diff --git a/main/sc/inc/compiler.hxx b/main/sc/inc/compiler.hxx
index 1cffb2b3dc..77c23d0989 100644
--- a/main/sc/inc/compiler.hxx
+++ b/main/sc/inc/compiler.hxx
@@ -56,7 +56,7 @@
 
 // constants and data types also for external modules (ScInterpreter et al)
 
-#define MAXCODE      512    /* maximum number of tokens in formula */
+#define MAXCODE      2048   /* maximum number of tokens in formula */
 #define MAXSTRLEN    1024   /* maximum length of input string of one symbol */
 #define MAXJUMPCOUNT 32     /* maximum number of jumps (ocChose) */
 
diff --git a/main/sc/source/core/inc/interpre.hxx 
b/main/sc/source/core/inc/interpre.hxx
index 43fa52d14c..8fbd240954 100644
--- a/main/sc/source/core/inc/interpre.hxx
+++ b/main/sc/source/core/inc/interpre.hxx
@@ -90,7 +90,7 @@ private:
 
 class ScToken;
 
-#define MAXSTACK      (4096 / sizeof(formula::FormulaToken*))
+#define MAXSTACK      (16384 / sizeof(formula::FormulaToken*))
 
 class ScTokenStack
 {
diff --git a/main/sc/source/core/tool/compiler.cxx 
b/main/sc/source/core/tool/compiler.cxx
index 36ab8bcb57..6429e64eaa 100644
--- a/main/sc/source/core/tool/compiler.cxx
+++ b/main/sc/source/core/tool/compiler.cxx
@@ -3970,6 +3970,14 @@ ScTokenArray* ScCompiler::CompileString( const String& 
rFormula )
                 aCorrectedFormula += mxSymbols->getSymbol(ocClose);
         }
     }
+    if ( aArr.GetLen() >= MAXCODE )
+    {
+        // keep the whole text, the tokens that fit would be written back as a 
shorter formula
+        aArr.Clear();
+        aArr.AddBad( aFormula.Copy( nForced ) );
+        aArr.SetCodeError( errCodeOverflow );
+        bCorrected = sal_False;     // the corrected text stops where the 
tokens did
+    }
     if ( nForced >= 2 )
         pArr->SetRecalcModeForced();
 
diff --git a/main/sc/source/core/tool/interpr4.cxx 
b/main/sc/source/core/tool/interpr4.cxx
index bf5a6ddc77..86184201a0 100644
--- a/main/sc/source/core/tool/interpr4.cxx
+++ b/main/sc/source/core/tool/interpr4.cxx
@@ -4034,7 +4034,12 @@ StackVar ScInterpreter::Interpret()
         nRetFmtIndex = 0;
 
     if (nGlobalError && GetStackType() != svError )
+    {
+        // after errStackOverflow the push would fail and a stale value become 
the result
+        if ( sp >= MAXSTACK )
+            Pop();
         PushError( nGlobalError);
+    }
 
     // THE final result.
     xResult = PopToken();
diff --git a/main/sc/source/ui/view/viewfunc.cxx 
b/main/sc/source/ui/view/viewfunc.cxx
index 0d53e5d2e8..89627526b2 100644
--- a/main/sc/source/ui/view/viewfunc.cxx
+++ b/main/sc/source/ui/view/viewfunc.cxx
@@ -525,6 +525,24 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab, const String& rS
                                        }
                                }
                        } while ( bAgain );
+                       if ( pArr->GetCodeError() == errCodeOverflow )
+                       {
+                               // refuse a formula that cannot be held, as 
other spreadsheets do
+                               delete pArr;
+                               if ( bRecord )
+                               {
+                                       for ( SCTAB k = 0; k < nUndoPos; k++ )
+                                               if ( ppOldCells[k] )
+                                                       ppOldCells[k]->Delete();
+                                       delete[] ppOldCells;
+                                       delete[] pHasFormat;
+                                       delete[] pOldFormats;
+                                       delete[] pTabs;
+                                       delete pUndoData;
+                               }
+                               ErrorMessage( STR_LONG_ERR_CODE_OVF );
+                               return;
+                       }
                        // um in mehreren Tabellen eingesetzt zu werden, muss 
die Formel
                        // via ScFormulaCell copy-ctor evtl. wegen RangeNames 
neu kompiliert
                        // werden, gleiches Code-Array fuer alle Zellen geht 
nicht.

Reply via email to