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.
