diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2020-04-28 13:50:01 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2020-04-28 15:07:45 +0200 |
commit | 679163845bd2f8b6de703f8fe704eb8912bc4ba4 (patch) | |
tree | 3bacb2d7758859b5bb052f34dcbaea89c485939d /cppu/source | |
parent | 8e7b61c48544b722b1cea41c9e2e6b1e01191be9 (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.cxx | 110 |
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; |