summaryrefslogtreecommitdiff
path: root/cppu/source
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-04-28 13:50:01 +0200
committerStephan Bergmann <sbergman@redhat.com>2020-04-28 15:07:45 +0200
commit679163845bd2f8b6de703f8fe704eb8912bc4ba4 (patch)
tree3bacb2d7758859b5bb052f34dcbaea89c485939d /cppu/source
parent8e7b61c48544b722b1cea41c9e2e6b1e01191be9 (diff)
tdf#115399: Don't kill pre-existing typelib_TypeDescription members
...in typelib_typedescription_register, in case they are already being referenced from elsewhere. Instead, only move from *ppNewDescription to pTDR->pType those members that were not yet initialized in the latter. Change-Id: I7620219d137f8dd7f24a0f4a04eda30669b6c5a9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93062 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'cppu/source')
-rw-r--r--cppu/source/typelib/typelib.cxx110
1 files changed, 94 insertions, 16 deletions
diff --git a/cppu/source/typelib/typelib.cxx b/cppu/source/typelib/typelib.cxx
index d1a503e4265b..e16c2eb90319 100644
--- a/cppu/source/typelib/typelib.cxx
+++ b/cppu/source/typelib/typelib.cxx
@@ -23,6 +23,7 @@
#include <cassert>
#include <list>
#include <set>
+#include <utility>
#include <vector>
#include <memory>
@@ -1486,23 +1487,100 @@ extern "C" void SAL_CALL typelib_typedescription_register(
if (pTDR->pType->pWeakRef) // if init
{
- typelib_typedescription_destructExtendedMembers( pTDR->pType );
+ switch (pTDR->pType->eTypeClass) {
+ case typelib_TypeClass_ENUM:
+ {
+ auto const src = reinterpret_cast<typelib_EnumTypeDescription *>(
+ *ppNewDescription);
+ auto const dst = reinterpret_cast<typelib_EnumTypeDescription *>(
+ pTDR->pType);
+ assert(dst->nEnumValues == 0);
+ assert(dst->ppEnumNames == nullptr);
+ assert(dst->pEnumValues == nullptr);
+ std::swap(src->nEnumValues, dst->nEnumValues);
+ std::swap(src->ppEnumNames, dst->ppEnumNames);
+ std::swap(src->pEnumValues, dst->pEnumValues);
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ auto const src = reinterpret_cast<typelib_CompoundTypeDescription *>(
+ *ppNewDescription);
+ auto const dst = reinterpret_cast<typelib_CompoundTypeDescription *>(
+ pTDR->pType);
+ assert(
+ (dst->pBaseTypeDescription == nullptr)
+ == (src->pBaseTypeDescription == nullptr));
+ assert(dst->nMembers == src->nMembers);
+ assert((dst->pMemberOffsets == nullptr) == (dst->nMembers == 0));
+ assert((dst->ppTypeRefs == nullptr) == (dst->nMembers == 0));
+ assert(dst->ppMemberNames == nullptr);
+ assert(
+ pTDR->pType->eTypeClass != typelib_TypeClass_STRUCT
+ || ((reinterpret_cast<typelib_StructTypeDescription *>(
+ dst)->pParameterizedTypes
+ == nullptr)
+ == (reinterpret_cast<typelib_StructTypeDescription *>(
+ src)->pParameterizedTypes
+ == nullptr)));
+ std::swap(src->ppMemberNames, dst->ppMemberNames);
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ auto const src = reinterpret_cast<typelib_InterfaceTypeDescription *>(
+ *ppNewDescription);
+ auto const dst = reinterpret_cast<typelib_InterfaceTypeDescription *>(
+ pTDR->pType);
+ assert(
+ (dst->pBaseTypeDescription == nullptr)
+ == (src->pBaseTypeDescription == nullptr));
+ assert(dst->nMembers == 0);
+ assert(dst->ppMembers == nullptr);
+ assert(dst->nAllMembers == 0);
+ assert(dst->ppAllMembers == nullptr);
+ assert(dst->pMapMemberIndexToFunctionIndex == nullptr);
+ assert(dst->nMapFunctionIndexToMemberIndex == 0);
+ assert(dst->pMapFunctionIndexToMemberIndex == nullptr);
+ assert(dst->nBaseTypes == src->nBaseTypes);
+ assert((dst->ppBaseTypes == nullptr) == (src->ppBaseTypes == nullptr));
+ std::swap(src->nMembers, dst->nMembers);
+ std::swap(src->ppMembers, dst->ppMembers);
+ std::swap(src->nAllMembers, dst->nAllMembers);
+ std::swap(src->ppAllMembers, dst->ppAllMembers);
+ std::swap(
+ src->pMapMemberIndexToFunctionIndex,
+ dst->pMapMemberIndexToFunctionIndex);
+ std::swap(
+ src->nMapFunctionIndexToMemberIndex,
+ dst->nMapFunctionIndexToMemberIndex);
+ std::swap(
+ src->pMapFunctionIndexToMemberIndex,
+ dst->pMapFunctionIndexToMemberIndex);
+ break;
+ }
+ default:
+ assert(false); // this cannot happen
+ }
+ }
+ else
+ {
+ // pTDR->pType->pWeakRef == 0 means that the description is empty
+ // description is not weak and the not the same
+ sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
+
+ // copy all specific data for the descriptions
+ memcpy(
+ pTDR->pType +1,
+ *ppNewDescription +1,
+ nSize - sizeof(typelib_TypeDescription) );
+
+ memset(
+ *ppNewDescription +1,
+ 0,
+ nSize - sizeof( typelib_TypeDescription ) );
}
-
- // pTDR->pType->pWeakRef == 0 means that the description is empty
- // description is not weak and the not the same
- sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
-
- // copy all specific data for the descriptions
- memcpy(
- pTDR->pType +1,
- *ppNewDescription +1,
- nSize - sizeof(typelib_TypeDescription) );
-
- memset(
- *ppNewDescription +1,
- 0,
- nSize - sizeof( typelib_TypeDescription ) );
pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
pTDR->pType->nSize = (*ppNewDescription)->nSize;