Blame SOURCES/0001-Obtain-actual-0-parameter-count-for-OR-AND-and-1-par.patch

228e4d
From 30a28017ec9ffd7e26bb7867be1597250cceee23 Mon Sep 17 00:00:00 2001
228e4d
From: Eike Rathke <erack@redhat.com>
228e4d
Date: Thu, 16 Feb 2023 20:20:31 +0100
228e4d
Subject: [PATCH] Obtain actual 0-parameter count for OR(), AND() and
228e4d
 1-parameter functions
228e4d
228e4d
OR and AND for legacy infix notation are classified as binary
228e4d
operators but in fact are functions with parameter count. In case
228e4d
no argument is supplied, GetByte() returns 0 and for that case the
228e4d
implicit binary operator 2 parameters were wrongly assumed.
228e4d
Similar for functions expecting 1 parameter, without argument 1
228e4d
was assumed. For "real" unary and binary operators the compiler
228e4d
already checks parameters. Omit OR and AND and 1-parameter
228e4d
functions from this implicit assumption and return the actual 0
228e4d
count.
228e4d
228e4d
Change-Id: Ie05398c112a98021ac2875cf7b6de994aee9d882
228e4d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147173
228e4d
Reviewed-by: Eike Rathke <erack@redhat.com>
228e4d
Tested-by: Jenkins
228e4d
228e4d
(cherry picked from commit e7ce9bddadb2db222eaa5f594ef1de2e36d57e5c)
228e4d
Conflicts:
228e4d
        sc/source/core/tool/interpr4.cxx
228e4d
228e4d
erAck: backported to 6.0.6.1
228e4d
---
228e4d
 formula/source/core/api/token.cxx | 13 +++++--------
228e4d
 sc/source/core/tool/interpr4.cxx  | 10 +++++++++-
228e4d
 2 files changed, 14 insertions(+), 9 deletions(-)
228e4d
228e4d
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
228e4d
index 07ff7cc..0964dc4 100644
228e4d
--- a/formula/source/core/api/token.cxx
228e4d
+++ b/formula/source/core/api/token.cxx
228e4d
@@ -106,17 +106,14 @@ sal_uInt8 FormulaToken::GetParamCount() const
228e4d
         return 0;       // parameters and specials
228e4d
                         // ocIf, ocIfError, ocIfNA and ocChoose not for FAP, have cByte then
228e4d
 //2do: bool parameter whether FAP or not?
228e4d
-    else if ( GetByte() )
228e4d
+    else if (GetByte())
228e4d
         return GetByte();   // all functions, also ocExternal and ocMacro
228e4d
-    else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP)
228e4d
-        return 2;           // binary
228e4d
-    else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP)
228e4d
-            || eOp == ocPercentSign)
228e4d
-        return 1;           // unary
228e4d
+    else if (SC_OPCODE_START_BIN_OP <= eOp && eOp < SC_OPCODE_STOP_BIN_OP && eOp != ocAnd && eOp != ocOr)
228e4d
+        return 2;           // binary operators, compiler checked; OR and AND legacy but are functions
228e4d
+    else if ((SC_OPCODE_START_UN_OP <= eOp && eOp < SC_OPCODE_STOP_UN_OP) || eOp == ocPercentSign)
228e4d
+        return 1;           // unary operators, compiler checked
228e4d
     else if (SC_OPCODE_START_NO_PAR <= eOp && eOp < SC_OPCODE_STOP_NO_PAR)
228e4d
         return 0;           // no parameter
228e4d
-    else if (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR)
228e4d
-        return 1;           // one parameter
228e4d
     else if ( eOp == ocIf || eOp == ocIfError || eOp == ocIfNA || eOp == ocChoose )
228e4d
         return 1;           // only the condition counts as parameter
228e4d
     else
228e4d
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
228e4d
index 904fecd..405d8dc 100644
228e4d
--- a/sc/source/core/tool/interpr4.cxx
228e4d
+++ b/sc/source/core/tool/interpr4.cxx
228e4d
@@ -4030,7 +4030,15 @@ StackVar ScInterpreter::Interpret()
228e4d
                     nStackBase = sp - pCur->GetParamCount();
228e4d
             }
228e4d
             if ( nStackBase > sp )
228e4d
-                nStackBase = sp;        // underflow?!?
228e4d
+            {
228e4d
+                SAL_WARN("sc.core", "Stack anomaly at " << aPos.Format(
228e4d
+                            ScRefFlags::VALID | ScRefFlags::FORCE_DOC | ScRefFlags::TAB_3D, pDok)
228e4d
+                        << "  eOp: " << static_cast<int>(eOp)
228e4d
+                        << "  params: " << static_cast<int>(pCur->GetParamCount())
228e4d
+                        << "  nStackBase: " << nStackBase << "  sp: " << sp);
228e4d
+                nStackBase = sp;
228e4d
+                assert(!"underflow");
228e4d
+            }
228e4d
 
228e4d
             switch( eOp )
228e4d
             {
228e4d
-- 
228e4d
2.44.0
228e4d