basic/source/classes/sb.cxx                       |    2 
 basic/source/classes/sbxmod.cxx                   |   28 +++++----
 basic/source/comp/parser.cxx                      |    6 +-
 basic/source/runtime/runtime.cxx                  |    2 
 basic/source/runtime/stdobj.cxx                   |    2 
 basic/source/sbx/sbxexec.cxx                      |   66 +++++++++++++---------
 include/basic/sbmod.hxx                           |   10 ++-
 include/basic/sbxobj.hxx                          |    3 +
 include/unotest/macros_test.hxx                   |    3 -
 sc/qa/extras/testdocuments/ForEachInSelection.ods |binary
 sc/qa/extras/vba-macro-test.cxx                   |   31 ++++++++++
 sc/source/core/tool/interpr4.cxx                  |    2 
 unotest/source/cpp/macros_test.cxx                |    9 +--
 13 files changed, 110 insertions(+), 54 deletions(-)

New commits:
commit ccd0ef98f76011f108f8ea1d282b96386dba0a6a
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Mon Feb 20 16:16:40 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Tue Feb 21 04:30:34 2023 +0000

    tdf#153752: SbxObject::Execute: extra characters in Option Compatible mode
    
    Change-Id: Ib3e4bd9eb9a249123a686f2434ded7b529fb050f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147345
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx
index f1ab6dd1da0c..0296e2238ca1 100644
--- a/basic/source/classes/sb.cxx
+++ b/basic/source/classes/sb.cxx
@@ -744,7 +744,7 @@ SbClassModuleObject::SbClassModuleObject( SbModule* 
pClassModule )
         }
     }
     SetModuleType( ModuleType::CLASS );
-    mbVBACompat = pClassModule->mbVBACompat;
+    mbVBASupport = pClassModule->mbVBASupport;
 }
 
 SbClassModuleObject::~SbClassModuleObject()
diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx
index f38e729185db..aaad6cd9bb41 100644
--- a/basic/source/classes/sbxmod.cxx
+++ b/basic/source/classes/sbxmod.cxx
@@ -416,9 +416,9 @@ static bool getDefaultVBAMode( StarBASIC* pb )
 // A Basic module has set EXTSEARCH, so that the elements, that the module 
contains,
 // could be found from other module.
 
-SbModule::SbModule( const OUString& rName, bool bVBACompat )
+SbModule::SbModule( const OUString& rName, bool bVBASupport )
          : SbxObject( "StarBASICModule" ),
-           pBreaks(nullptr), mbVBACompat( bVBACompat ), bIsProxyModule( false )
+           pBreaks(nullptr), mbVBASupport(bVBASupport), mbCompat(bVBASupport), 
bIsProxyModule(false)
 {
     SetName( rName );
     SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::GlobalSearch );
@@ -802,11 +802,11 @@ void SbModule::Notify( SfxBroadcaster& rBC, const 
SfxHint& rHint )
 void SbModule::SetSource32( const OUString& r )
 {
     // Default basic mode to library container mode, but... allow Option 
VBASupport 0/1 override
-    SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) 
);
+    SetVBASupport( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) 
) );
     aOUSource = r;
     StartDefinitions();
     SbiTokenizer aTok( r );
-    aTok.SetCompatible( IsVBACompat() );
+    aTok.SetCompatible( IsVBASupport() );
 
     while( !aTok.IsEof() )
     {
@@ -837,12 +837,13 @@ void SbModule::SetSource32( const OUString& r )
                     eCurTok = aTok.Next();
                     if( eCurTok == COMPATIBLE )
                     {
+                        mbCompat = true;
                         aTok.SetCompatible( true );
                     }
                     else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == 
NUMBER ) )
                     {
                         bool bIsVBA = ( aTok.GetDbl()== 1 );
-                        SetVBACompat( bIsVBA );
+                        SetVBASupport( bIsVBA );
                         aTok.SetCompatible( bIsVBA );
                     }
                 }
@@ -974,15 +975,16 @@ static void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic )
 }
 
 
-void SbModule::SetVBACompat( bool bCompat )
+void SbModule::SetVBASupport( bool bSupport )
 {
-    if( mbVBACompat == bCompat )
+    if( mbVBASupport == bSupport )
         return;
 
-    mbVBACompat = bCompat;
+    mbVBASupport = bSupport;
     // initialize VBA document API
-    if( mbVBACompat ) try
+    if( mbVBASupport ) try
     {
+        mbCompat = true;
         StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
         uno::Reference< lang::XMultiServiceFactory > xFactory( 
getDocumentModel( pBasic ), uno::UNO_QUERY_THROW );
         xFactory->createInstance( "ooo.vba.VBAGlobals" );
@@ -1067,7 +1069,7 @@ namespace
 // Run a Basic-subprogram
 void SbModule::Run( SbMethod* pMeth )
 {
-    SAL_INFO("basic","About to run " << pMeth->GetName() << ", vba compatmode 
is " << mbVBACompat );
+    SAL_INFO("basic","About to run " << pMeth->GetName() << ", vba compatmode 
is " << mbVBASupport );
 
     static sal_uInt16 nMaxCallLevel = 0;
 
@@ -1088,7 +1090,7 @@ void SbModule::Run( SbMethod* pMeth )
         /*  If a VBA script in a document is started, get the VBA compatibility
             interface from the document Basic library container, and notify all
             VBA script listeners about the started script. */
-        if( mbVBACompat )
+        if( mbVBASupport )
         {
             StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
             if( pBasic && pBasic->IsDocBasic() ) try
@@ -1169,7 +1171,7 @@ void SbModule::Run( SbMethod* pMeth )
             {
                 RunGuard xRuntimeGuard(this, pMeth, pMeth->nStart, pSbData, 
bDelInst);
 
-                if (mbVBACompat)
+                if (mbVBASupport)
                     pSbData->pInst->EnableCompatibility(true);
 
                 xRuntimeGuard.run();
@@ -2501,7 +2503,7 @@ void SbUserFormModule::triggerResizeEvent()
 
 SbUserFormModuleInstance* SbUserFormModule::CreateInstance()
 {
-    SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, 
GetName(), m_mInfo, IsVBACompat() );
+    SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, 
GetName(), m_mInfo, IsVBASupport() );
     return pInstance;
 }
 
diff --git a/basic/source/comp/parser.cxx b/basic/source/comp/parser.cxx
index 777db4071615..70bc27dcd16b 100644
--- a/basic/source/comp/parser.cxx
+++ b/basic/source/comp/parser.cxx
@@ -145,7 +145,7 @@ SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
 
     rTypeArray = new SbxArray; // array for user defined types
     rEnumArray = new SbxArray; // array for Enum types
-    bVBASupportOn = pm->IsVBACompat();
+    bVBASupportOn = pm->IsVBASupport();
     if ( bVBASupportOn )
         EnableCompatibility();
 
@@ -818,9 +818,9 @@ void SbiParser::Option()
                     }
                     // if the module setting is different
                     // reset it to what the Option tells us
-                    if ( bVBASupportOn != aGen.GetModule().IsVBACompat() )
+                    if ( bVBASupportOn != aGen.GetModule().IsVBASupport() )
                     {
-                        aGen.GetModule().SetVBACompat( bVBASupportOn );
+                        aGen.GetModule().SetVBASupport( bVBASupportOn );
                     }
                     break;
                 }
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
index e6f4f7b68a6b..060676cbb8e5 100644
--- a/basic/source/runtime/runtime.cxx
+++ b/basic/source/runtime/runtime.cxx
@@ -597,7 +597,7 @@ SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, 
sal_uInt32 nStart )
     pCode     =
     pStmnt    = pImg->GetCode() + nStart;
     refExprStk = new SbxArray;
-    SetVBAEnabled( pMod->IsVBACompat() );
+    SetVBAEnabled( pMod->IsVBASupport() );
     SetParameters( pe ? pe->GetParameters() : nullptr );
 }
 
diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx
index 215f879369df..a89fdebb0472 100644
--- a/basic/source/runtime/stdobj.cxx
+++ b/basic/source/runtime/stdobj.cxx
@@ -993,7 +993,7 @@ SbxVariable* SbiStdObject::Find( const OUString& rName, 
SbxClassType t )
                         // No instance running => compiling a source on module 
level.
                         const SbModule* pModule = GetSbData()->pCompMod;
                         if (pModule)
-                            bCompatibility = pModule->IsVBACompat();
+                            bCompatibility = pModule->IsVBASupport();
                     }
                     if ((bCompatibility && (NORMONLY_ & p->nArgs)) || 
(!bCompatibility && (COMPATONLY_ & p->nArgs)))
                         bFound = false;
diff --git a/basic/source/sbx/sbxexec.cxx b/basic/source/sbx/sbxexec.cxx
index f3abca766d35..de711944d36c 100644
--- a/basic/source/sbx/sbxexec.cxx
+++ b/basic/source/sbx/sbxexec.cxx
@@ -17,19 +17,23 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <sal/config.h>
+
+#include <basic/sbmod.hxx>
 #include <basic/sbx.hxx>
 #include <basic/sberrors.hxx>
 #include <rtl/character.hxx>
 #include <rtl/ustrbuf.hxx>
 
+#include <basiccharclass.hxx>
 
 static SbxVariableRef Element
     ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf,
-      SbxClassType );
+      SbxClassType, bool bCompatible );
 
 static const sal_Unicode* SkipWhitespace( const sal_Unicode* p )
 {
-    while( *p && ( *p == ' ' || *p == '\t' ) )
+    while( BasicCharClass::isWhitespace(*p) )
         p++;
     return p;
 }
@@ -37,7 +41,7 @@ static const sal_Unicode* SkipWhitespace( const sal_Unicode* 
p )
 // Scanning of a symbol. The symbol were inserted in rSym, the return value
 // is the new scan position. The symbol is at errors empty.
 
-static const sal_Unicode* Symbol( const sal_Unicode* p, OUString& rSym )
+static const sal_Unicode* Symbol( const sal_Unicode* p, OUString& rSym, bool 
bCompatible )
 {
     sal_uInt16 nLen = 0;
     // Did we have a nonstandard symbol?
@@ -54,7 +58,7 @@ static const sal_Unicode* Symbol( const sal_Unicode* p, 
OUString& rSym )
     else
     {
         // A symbol had to begin with an alphabetic character or an underline
-        if( !rtl::isAsciiAlpha( *p ) && *p != '_' )
+        if( !BasicCharClass::isAlpha( *p, bCompatible ) && *p != '_' )
         {
             SbxBase::SetError( ERRCODE_BASIC_SYNTAX );
         }
@@ -62,7 +66,7 @@ static const sal_Unicode* Symbol( const sal_Unicode* p, 
OUString& rSym )
         {
             rSym = p;
             // The it can contain alphabetic characters, numbers or underlines
-            while( *p && (rtl::isAsciiAlphanumeric( *p ) || *p == '_') )
+            while( *p && (BasicCharClass::isAlphaNumeric( *p, bCompatible ) || 
*p == '_') )
             {
                 p++;
                 nLen++;
@@ -81,15 +85,15 @@ static const sal_Unicode* Symbol( const sal_Unicode* p, 
OUString& rSym )
 // Qualified name. Element.Element...
 
 static SbxVariableRef QualifiedName
-    ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, 
SbxClassType t )
+    ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, 
SbxClassType t, bool bCompatible )
 {
 
     SbxVariableRef refVar;
     const sal_Unicode* p = SkipWhitespace( *ppBuf );
-    if( rtl::isAsciiAlpha( *p ) || *p == '_' || *p == '[' )
+    if( BasicCharClass::isAlpha( *p, bCompatible ) || *p == '_' || *p == '[' )
     {
         // Read in the element
-        refVar = Element( pObj, pGbl, &p, t );
+        refVar = Element( pObj, pGbl, &p, t, bCompatible );
         while( refVar.is() && (*p == '.' || *p == '!') )
         {
             // It follows still an objectelement. The current element
@@ -103,7 +107,7 @@ static SbxVariableRef QualifiedName
                 break;
             p++;
             // And the next element please
-            refVar = Element( pObj, pGbl, &p, t );
+            refVar = Element( pObj, pGbl, &p, t, bCompatible );
         }
     }
     else
@@ -116,7 +120,7 @@ static SbxVariableRef QualifiedName
 // a function (with optional parameters).
 
 static SbxVariableRef Operand
-    ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, bool bVar )
+    ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf, bool bVar, 
bool bCompatible )
 {
     SbxVariableRef refVar( new SbxVariable );
     const sal_Unicode* p = SkipWhitespace( *ppBuf );
@@ -159,7 +163,7 @@ static SbxVariableRef Operand
     }
     else
     {
-        refVar = QualifiedName( pObj, pGbl, &p, SbxClassType::DontCare );
+        refVar = QualifiedName( pObj, pGbl, &p, SbxClassType::DontCare, 
bCompatible );
     }
     *ppBuf = p;
     return refVar;
@@ -168,15 +172,15 @@ static SbxVariableRef Operand
 // Read in of a simple term. The operands +, -, * and /
 // are supported.
 
-static SbxVariableRef MulDiv( SbxObject* pObj, SbxObject* pGbl, const 
sal_Unicode** ppBuf )
+static SbxVariableRef MulDiv( SbxObject* pObj, SbxObject* pGbl, const 
sal_Unicode** ppBuf, bool bCompatible )
 {
     const sal_Unicode* p = *ppBuf;
-    SbxVariableRef refVar( Operand( pObj, pGbl, &p, false ) );
+    SbxVariableRef refVar( Operand( pObj, pGbl, &p, false, bCompatible ) );
     p = SkipWhitespace( p );
     while( refVar.is() && ( *p == '*' || *p == '/' ) )
     {
         sal_Unicode cOp = *p++;
-        SbxVariableRef refVar2( Operand( pObj, pGbl, &p, false ) );
+        SbxVariableRef refVar2( Operand( pObj, pGbl, &p, false, bCompatible ) 
);
         if( refVar2.is() )
         {
             // temporary variable!
@@ -198,15 +202,15 @@ static SbxVariableRef MulDiv( SbxObject* pObj, SbxObject* 
pGbl, const sal_Unicod
     return refVar;
 }
 
-static SbxVariableRef PlusMinus( SbxObject* pObj, SbxObject* pGbl, const 
sal_Unicode** ppBuf )
+static SbxVariableRef PlusMinus( SbxObject* pObj, SbxObject* pGbl, const 
sal_Unicode** ppBuf, bool bCompatible )
 {
     const sal_Unicode* p = *ppBuf;
-    SbxVariableRef refVar( MulDiv( pObj, pGbl, &p ) );
+    SbxVariableRef refVar( MulDiv( pObj, pGbl, &p, bCompatible ) );
     p = SkipWhitespace( p );
     while( refVar.is() && ( *p == '+' || *p == '-' ) )
     {
         sal_Unicode cOp = *p++;
-        SbxVariableRef refVar2( MulDiv( pObj, pGbl, &p ) );
+        SbxVariableRef refVar2( MulDiv( pObj, pGbl, &p, bCompatible ) );
         if( refVar2.is() )
         {
             // temporary Variable!
@@ -228,10 +232,10 @@ static SbxVariableRef PlusMinus( SbxObject* pObj, 
SbxObject* pGbl, const sal_Uni
     return refVar;
 }
 
-static SbxVariableRef Assign( SbxObject* pObj, SbxObject* pGbl, const 
sal_Unicode** ppBuf )
+static SbxVariableRef Assign( SbxObject* pObj, SbxObject* pGbl, const 
sal_Unicode** ppBuf, bool bCompatible )
 {
     const sal_Unicode* p = *ppBuf;
-    SbxVariableRef refVar( Operand( pObj, pGbl, &p, true ) );
+    SbxVariableRef refVar( Operand( pObj, pGbl, &p, true, bCompatible ) );
     p = SkipWhitespace( p );
     if( refVar.is() )
     {
@@ -246,7 +250,7 @@ static SbxVariableRef Assign( SbxObject* pObj, SbxObject* 
pGbl, const sal_Unicod
             else
             {
                 p++;
-                SbxVariableRef refVar2( PlusMinus( pObj, pGbl, &p ) );
+                SbxVariableRef refVar2( PlusMinus( pObj, pGbl, &p, bCompatible 
) );
                 if( refVar2.is() )
                 {
                     SbxVariable* pVar = refVar.get();
@@ -270,10 +274,10 @@ static SbxVariableRef Assign( SbxObject* pObj, SbxObject* 
pGbl, const sal_Unicod
 
 static SbxVariableRef Element
     ( SbxObject* pObj, SbxObject* pGbl, const sal_Unicode** ppBuf,
-      SbxClassType t )
+      SbxClassType t, bool bCompatible )
 {
     OUString aSym;
-    const sal_Unicode* p = Symbol( *ppBuf, aSym );
+    const sal_Unicode* p = Symbol( *ppBuf, aSym, bCompatible );
     SbxVariableRef refVar;
     if( !aSym.isEmpty() )
     {
@@ -299,7 +303,7 @@ static SbxVariableRef Element
                 // Search parameter always global!
                 while( *p && *p != ')' && *p != ']' )
                 {
-                    SbxVariableRef refArg = PlusMinus( pGbl, pGbl, &p );
+                    SbxVariableRef refArg = PlusMinus( pGbl, pGbl, &p, 
bCompatible );
                     if( !refArg.is() )
                     {
                         // Error during the parsing
@@ -346,7 +350,7 @@ SbxVariable* SbxObject::Execute( const OUString& rTxt )
         {
             SetError( ERRCODE_BASIC_SYNTAX ); break;
         }
-        pVar = Assign( this, this, &p );
+        pVar = Assign( this, this, &p, IsModuleCompatible() );
         if( !pVar.is() )
         {
             break;
@@ -369,7 +373,7 @@ SbxVariable* SbxObject::FindQualified( const OUString& 
rName, SbxClassType t )
     {
         return nullptr;
     }
-    pVar = QualifiedName( this, this, &p, t );
+    pVar = QualifiedName( this, this, &p, t, IsModuleCompatible() );
     p = SkipWhitespace( p );
     if( *p )
     {
@@ -378,4 +382,16 @@ SbxVariable* SbxObject::FindQualified( const OUString& 
rName, SbxClassType t )
     return pVar.get();
 }
 
+bool SbxObject::IsModuleCompatible() const
+{
+    const SbxObject* pObj = this;
+    while (pObj)
+    {
+        if (auto pMod = dynamic_cast<const SbModule*>(pObj))
+            return pMod->IsCompatible();
+        pObj = pObj->GetParent();
+    }
+    return false;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basic/sbmod.hxx b/include/basic/sbmod.hxx
index a71f7253a451..fac7f9e50121 100644
--- a/include/basic/sbmod.hxx
+++ b/include/basic/sbmod.hxx
@@ -66,7 +66,8 @@ protected:
     std::unique_ptr<SbiImage> pImage;        // the Image
     SbiBreakpoints*     pBreaks;       // Breakpoints
     std::unique_ptr<SbClassData> pClassData;
-    bool mbVBACompat;
+    bool mbVBASupport; // Option VBASupport
+    bool mbCompat; // Option Compatible
     sal_Int32 mnType;
     SbxObjectRef pDocObject; // an impl object ( used by Document Modules )
     bool    bIsProxyModule;
@@ -95,7 +96,7 @@ protected:
     virtual ~SbModule() override;
 public:
     SBX_DECL_PERSIST_NODATA(SBXID_BASICMOD,2);
-                    SbModule( const OUString&, bool bCompat = false );
+                    SbModule( const OUString&, bool bVBASupport = false );
     SAL_DLLPRIVATE virtual void SetParent( SbxObject* ) override;
     SAL_DLLPRIVATE virtual void Clear() override;
 
@@ -120,8 +121,9 @@ public:
     SAL_DLLPRIVATE bool ExceedsLegacyModuleSize();
     SAL_DLLPRIVATE void fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg = 
nullptr ) const;
     SAL_DLLPRIVATE bool HasExeCode();
-    bool     IsVBACompat() const { return mbVBACompat;}
-    SAL_DLLPRIVATE void SetVBACompat( bool bCompat );
+    bool     IsVBASupport() const { return mbVBASupport; }
+    SAL_DLLPRIVATE void SetVBASupport( bool bSupport );
+    bool     IsCompatible() const { return mbCompat; }
     sal_Int32 GetModuleType() const { return mnType; }
     void     SetModuleType( sal_Int32 nType ) { mnType = nType; }
     bool     isProxyModule() const { return bIsProxyModule; }
diff --git a/include/basic/sbxobj.hxx b/include/basic/sbxobj.hxx
index 10d4c074c423..34c117d33853 100644
--- a/include/basic/sbxobj.hxx
+++ b/include/basic/sbxobj.hxx
@@ -78,6 +78,9 @@ public:
     SbxArray* GetObjects()      { return pObjs.get(); }
     // Debugging
     void Dump( SvStream&, bool bDumpAll );
+
+private:
+    bool IsModuleCompatible() const; // Module's Option Compatible
 };
 
 #endif // INCLUDED_BASIC_SBXOBJ_HXX
diff --git a/include/unotest/macros_test.hxx b/include/unotest/macros_test.hxx
index e6c3ecce9683..c960ff76ea26 100644
--- a/include/unotest/macros_test.hxx
+++ b/include/unotest/macros_test.hxx
@@ -20,6 +20,7 @@
 
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/frame/XDesktop2.hpp>
+#include <com/sun/star/uno/Any.h>
 #include <utility>
 
 struct TestMacroInfo
@@ -86,7 +87,7 @@ public:
                     const css::uno::Sequence<css::beans::PropertyValue>& 
rExtra_args
                     = css::uno::Sequence<css::beans::PropertyValue>());
 
-    static void
+    static css::uno::Any
     dispatchCommand(const css::uno::Reference<css::lang::XComponent>& 
xComponent,
                     const OUString& rCommand,
                     const css::uno::Sequence<css::beans::PropertyValue>& 
rPropertyValues);
diff --git a/sc/qa/extras/testdocuments/ForEachInSelection.ods 
b/sc/qa/extras/testdocuments/ForEachInSelection.ods
index 7996c86eb953..8706bfa8cb17 100644
Binary files a/sc/qa/extras/testdocuments/ForEachInSelection.ods and 
b/sc/qa/extras/testdocuments/ForEachInSelection.ods differ
diff --git a/sc/qa/extras/vba-macro-test.cxx b/sc/qa/extras/vba-macro-test.cxx
index 2464996d2812..73dab6bba921 100644
--- a/sc/qa/extras/vba-macro-test.cxx
+++ b/sc/qa/extras/vba-macro-test.cxx
@@ -24,6 +24,8 @@
 #include <scitems.hxx>
 #include <sortparam.hxx>
 
+#include <com/sun/star/frame/DispatchResultEvent.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
 #include <com/sun/star/sheet/XSpreadsheet.hpp>
 #include <com/sun/star/sheet/XPrintAreas.hpp>
 #include <com/sun/star/table/CellRangeAddress.hpp>
@@ -69,6 +71,7 @@ public:
     void testTdf126457();
     void testVbaPDFExport();
     void testForEachInSelection();
+    void testNonAsciiMacroIRI();
 
     CPPUNIT_TEST_SUITE(VBAMacroTest);
     CPPUNIT_TEST(testSimpleCopyAndPaste);
@@ -94,6 +97,7 @@ public:
     CPPUNIT_TEST(testTdf126457);
     CPPUNIT_TEST(testVbaPDFExport);
     CPPUNIT_TEST(testForEachInSelection);
+    CPPUNIT_TEST(testNonAsciiMacroIRI);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -902,6 +906,33 @@ void VBAMacroTest::testForEachInSelection()
     CPPUNIT_ASSERT_EQUAL(OUString("zab"), rDoc.GetString(ScAddress(0, 2, 0)));
 }
 
+void VBAMacroTest::testNonAsciiMacroIRI()
+{
+    loadFromURL(u"ForEachInSelection.ods");
+    SfxObjectShell* pFoundShell = 
SfxObjectShell::GetShellFromComponent(mxComponent);
+
+    CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
+    ScDocShell* pDocSh = static_cast<ScDocShell*>(pFoundShell);
+    ScDocument& rDoc = pDocSh->GetDocument();
+
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), rDoc.GetString(ScAddress(0, 0, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("bar"), rDoc.GetString(ScAddress(0, 1, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("baz"), rDoc.GetString(ScAddress(0, 2, 0)));
+
+    auto ret = dispatchCommand(mxComponent, 
u"macro://./Standard.Module1.NonAsciiName_αβγ", {});
+    css::frame::DispatchResultEvent retEvent;
+    CPPUNIT_ASSERT(ret >>= retEvent);
+    // tdf#153752: without the fix, this would fail with
+    // equality assertion failed
+    // - Expected: 1
+    // - Actual  : 0
+    CPPUNIT_ASSERT_EQUAL(css::frame::DispatchResultState::SUCCESS, 
retEvent.State);
+
+    CPPUNIT_ASSERT_EQUAL(OUString("oof"), rDoc.GetString(ScAddress(0, 0, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("rab"), rDoc.GetString(ScAddress(0, 1, 0)));
+    CPPUNIT_ASSERT_EQUAL(OUString("zab"), rDoc.GetString(ScAddress(0, 2, 0)));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(VBAMacroTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 1f14981ebadc..7d46a39ad037 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3259,7 +3259,7 @@ void ScInterpreter::ScMacro()
     bool bVolatileMacro = false;
 
     SbModule* pModule = pMethod->GetModule();
-    bool bUseVBAObjects = pModule->IsVBACompat();
+    bool bUseVBAObjects = pModule->IsVBASupport();
     SbxObject* pObject = pModule->GetParent();
     OSL_ENSURE(dynamic_cast<const StarBASIC *>(pObject) != nullptr, "No Basic 
found!");
     OUString aMacroStr = pObject->GetName() + "." + pModule->GetName() + "." + 
pMethod->GetName();
diff --git a/unotest/source/cpp/macros_test.cxx 
b/unotest/source/cpp/macros_test.cxx
index a8b8f6bdf572..36438b2e50ec 100644
--- a/unotest/source/cpp/macros_test.cxx
+++ b/unotest/source/cpp/macros_test.cxx
@@ -75,9 +75,10 @@ MacrosTest::loadFromDesktop(const OUString& rURL, const 
OUString& rDocService,
     return xComponent;
 }
 
-void MacrosTest::dispatchCommand(const uno::Reference<lang::XComponent>& 
xComponent,
-                                 const OUString& rCommand,
-                                 const uno::Sequence<beans::PropertyValue>& 
rPropertyValues)
+css::uno::Any
+MacrosTest::dispatchCommand(const uno::Reference<lang::XComponent>& xComponent,
+                            const OUString& rCommand,
+                            const uno::Sequence<beans::PropertyValue>& 
rPropertyValues)
 {
     uno::Reference<frame::XController> xController
         = uno::Reference<frame::XModel>(xComponent, 
uno::UNO_QUERY_THROW)->getCurrentController();
@@ -89,7 +90,7 @@ void MacrosTest::dispatchCommand(const 
uno::Reference<lang::XComponent>& xCompon
     uno::Reference<frame::XDispatchHelper> 
xDispatchHelper(frame::DispatchHelper::create(xContext));
     CPPUNIT_ASSERT(xDispatchHelper.is());
 
-    xDispatchHelper->executeDispatch(xFrame, rCommand, OUString(), 0, 
rPropertyValues);
+    return xDispatchHelper->executeDispatch(xFrame, rCommand, OUString(), 0, 
rPropertyValues);
 }
 
 std::unique_ptr<SvStream> MacrosTest::parseExportStream(const OUString& url,

Reply via email to