summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2016-06-14 15:48:52 +0100
committerCaolán McNamara <caolanm@redhat.com>2016-06-14 19:54:26 +0000
commit9f0997eb167d0ef2193a59d43ab55ea5f13ebaac (patch)
tree815c61b4c26e17a1f51c503f4f1090b2b6b102c4
parentbe2cf3d28b91cff4127c95cfe4481f36bdeb24fb (diff)
Resolves: tdf#59222 Crash in Basic with an array of values...
from a range address trying to make all SbxVariables reference count their parents is ludiciously hard, so just reference count this one known crashing case Change-Id: Ie1fa6624e8184146dd00d766cdbacef674153ef6 Reviewed-on: https://gerrit.libreoffice.org/26272 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--basic/source/runtime/methods1.cxx2
-rw-r--r--basic/source/sbx/sbxvar.cxx15
-rw-r--r--include/basic/sbxobj.hxx2
-rw-r--r--include/basic/sbxvar.hxx11
4 files changed, 27 insertions, 3 deletions
diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx
index 3a361038a344..6bddfd5c8570 100644
--- a/basic/source/runtime/methods1.cxx
+++ b/basic/source/runtime/methods1.cxx
@@ -830,7 +830,7 @@ RTLFUNC(Array)
for( sal_uInt16 i = 0 ; i < nArraySize ; i++ )
{
SbxVariable* pVar = rPar.Get(i+1);
- SbxVariable* pNew = new SbxVariable( *pVar );
+ SbxVariable* pNew = new SbxEnsureParentVariable(*pVar);
pNew->SetFlag( SbxFlagBits::Write );
short index = static_cast< short >(i);
if ( bIncIndex )
diff --git a/basic/source/sbx/sbxvar.cxx b/basic/source/sbx/sbxvar.cxx
index 23d7bfe29ed3..0977c7449d02 100644
--- a/basic/source/sbx/sbxvar.cxx
+++ b/basic/source/sbx/sbxvar.cxx
@@ -100,6 +100,21 @@ SbxVariable::SbxVariable( const SbxVariable& r )
}
}
+SbxEnsureParentVariable::SbxEnsureParentVariable(const SbxVariable& r)
+ : SbxVariable(r)
+ , xParent(const_cast<SbxVariable&>(r).GetParent())
+{
+ assert(GetParent() == xParent.get());
+}
+
+void SbxEnsureParentVariable::SetParent(SbxObject* p)
+{
+ assert(GetParent() == xParent.get());
+ SbxVariable::SetParent(p);
+ xParent = SbxObjectRef(p);
+ assert(GetParent() == xParent.get());
+}
+
SbxVariable::SbxVariable( SbxDataType t, void* p ) : SbxValue( t, p )
{
pCst = nullptr;
diff --git a/include/basic/sbxobj.hxx b/include/basic/sbxobj.hxx
index f80c0fc4967f..80449e20065c 100644
--- a/include/basic/sbxobj.hxx
+++ b/include/basic/sbxobj.hxx
@@ -81,8 +81,6 @@ public:
void Dump( SvStream&, bool bDumpAll=false );
};
-typedef tools::SvRef<SbxObject> SbxObjectRef;
-
#endif // INCLUDED_BASIC_SBXOBJ_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basic/sbxvar.hxx b/include/basic/sbxvar.hxx
index 3ee3768a2a07..25ac2605d859 100644
--- a/include/basic/sbxvar.hxx
+++ b/include/basic/sbxvar.hxx
@@ -283,8 +283,19 @@ public:
static sal_uInt16 MakeHashCode( const OUString& rName );
};
+typedef tools::SvRef<SbxObject> SbxObjectRef;
typedef tools::SvRef<SbxVariable> SbxVariableRef;
+//tdf#59222 SbxEnsureParentVariable is a SbxVariable which keeps a reference to
+//its parent, ensuring it always exists while this SbxVariable exists
+class BASIC_DLLPUBLIC SbxEnsureParentVariable : public SbxVariable
+{
+ SbxObjectRef xParent;
+public:
+ SbxEnsureParentVariable(const SbxVariable& r);
+ virtual void SetParent(SbxObject* p) override;
+};
+
#endif // INCLUDED_BASIC_SBXVAR_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */