basctl/inc/strings.hrc | 1 + basctl/source/basicide/baside2b.cxx | 14 ++++++++++++-- basic/source/classes/sbunoobj.cxx | 22 ++++++++++++++++++++++ basic/source/inc/sbunoobj.hxx | 1 + include/basic/sbuno.hxx | 4 ++++ 5 files changed, 40 insertions(+), 2 deletions(-)
New commits: commit 78693c376ed1bdf6d859a44c2651030dc9c970f8 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Thu Nov 14 14:24:20 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Nov 14 18:02:03 2024 +0100 tdf#108189 inspection of object hangs LO There is no general solution to this that I am aware of, so just implement a rather specific solution that will need periodic extending to check for other dangerous properties Change-Id: Ie09d89416fea5b7cdf782319ed9921657faa5a5a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176593 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/basctl/inc/strings.hrc b/basctl/inc/strings.hrc index ee83fbb543b0..8dba3f960c93 100644 --- a/basctl/inc/strings.hrc +++ b/basctl/inc/strings.hrc @@ -114,6 +114,7 @@ #define RID_STR_MODULE_READONLY NC_("RID_STR_READONLY_WARNING", "This module is read-only and cannot be edited.") #define RID_STR_DIALOG_READONLY NC_("RID_STR_READONLY_WARNING", "This dialog is read-only and cannot be edited.") #define RID_LINE_STATUS_CONTROL NC_("RID_LINE_STATUS_CONTROL", "Current line and character. Click to open 'Go to Line' dialog.") +#define RID_VARIABLE_TOO_LARGE_TO_DISPLAY NC_("RID_VARIABLE_TOO_LARGE_TO_DISPLAY", "Variable too large to display in debugger") // Color scheme names #define RID_STR_COLORSCHEME_DEFAULT NC_("RID_STR_COLORSCHEME_DEFAULT", "Default") diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx index b3d44695740c..b7b75b958183 100644 --- a/basctl/source/basicide/baside2b.cxx +++ b/basctl/source/basicide/baside2b.cxx @@ -2314,7 +2314,13 @@ SbxBase* WatchWindow::ImplGetSBXForEntry(const weld::TreeIter& rEntry, bool& rbA // Force getting value SbxValues aRes; aRes.eType = SbxVOID; - pVar->Get( aRes ); + if (!isVeryLargeUnoProperty(pVar)) + pVar->Get( aRes ); + else + { + aRes.eType = SbxSTRING; + aRes.pOUString = new OUString("<" + IDEResId(RID_VARIABLE_TOO_LARGE_TO_DISPLAY) + ">"); + } } } // Array? @@ -2495,7 +2501,11 @@ void WatchWindow::UpdateWatches(bool bBasicStopped) { // extra treatment of arrays SbxDataType eType = pVar->GetType(); - if ( eType & SbxARRAY ) + if (isVeryLargeUnoProperty(pVar)) + { + aWatchStr += "<" + IDEResId(RID_VARIABLE_TOO_LARGE_TO_DISPLAY) + ">"; + } + else if ( eType & SbxARRAY ) { // consider multidimensional arrays! if (SbxDimArray* pNewArray = dynamic_cast<SbxDimArray*>(pVar->GetObject())) diff --git a/basic/source/classes/sbunoobj.cxx b/basic/source/classes/sbunoobj.cxx index 7f75e18bbe5b..25a395e7a6bf 100644 --- a/basic/source/classes/sbunoobj.cxx +++ b/basic/source/classes/sbunoobj.cxx @@ -40,6 +40,7 @@ #include <com/sun/star/script/ArrayWrapper.hpp> #include <com/sun/star/script/CannotConvertException.hpp> #include <com/sun/star/script/NativeObjectWrapper.hpp> +#include <com/sun/star/sheet/XSheetCellCursor.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/uno/DeploymentException.hpp> @@ -2585,6 +2586,27 @@ SbUnoProperty::SbUnoProperty SbUnoProperty::~SbUnoProperty() {} +bool isVeryLargeUnoProperty(SbxVariable const * pVar) +{ + auto pUnoVar = dynamic_cast<const SbUnoProperty*>(pVar); + if (!pUnoVar) + return false; + // The ScCellRangeObj methods will attempt to generate massive strings, + // which will use up massive amounts of RAM and also lock of the program + // for some time. + const OUString & aUnoName = pUnoVar->getUnoName(); + if (aUnoName == "DataArray" || aUnoName == "FormulaArray") + { + auto pParent = dynamic_cast<const SbUnoObject*>(pUnoVar->GetParent()); + if (!pParent) + return false; + css::uno::Any aAny = const_cast<SbUnoObject*>(pParent)->getUnoAny(); + css::uno::Reference<css::sheet::XSheetCellCursor> xCursor = aAny.query<css::sheet::XSheetCellCursor>(); + if (xCursor) + return true; + } + return false; +} SbxVariable* SbUnoObject::Find( const OUString& rName, SbxClassType t ) { diff --git a/basic/source/inc/sbunoobj.hxx b/basic/source/inc/sbunoobj.hxx index 4dee669219ef..16e32af5a87e 100644 --- a/basic/source/inc/sbunoobj.hxx +++ b/basic/source/inc/sbunoobj.hxx @@ -200,6 +200,7 @@ public: bool isInvocationBased() const { return mbInvocation; } SbxDataType getRealType() const { return mRealType; } + const OUString& getUnoName() const { return aUnoProp.Name; } }; // factory class to create uno-structs per DIM AS NEW diff --git a/include/basic/sbuno.hxx b/include/basic/sbuno.hxx index b19f0f5da249..cd35561db33a 100644 --- a/include/basic/sbuno.hxx +++ b/include/basic/sbuno.hxx @@ -41,4 +41,8 @@ css::uno::Any sbxToUnoValue( const SbxValue* pVar, const css::uno::Type& rType, BASIC_DLLPUBLIC void unoToSbxValue( SbxVariable* pVar, const css::uno::Any& aValue ); +/// Used by the BASIC debugger to detect very large UNO property values that should not be displayed +/// because they will stall the program. +BASIC_DLLPUBLIC bool isVeryLargeUnoProperty(const SbxVariable* pVar); + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */