From 7e7a83b73dad2a9a2c73826f61a81c4c774d2c9d Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 16 Aug 2013 22:15:49 +0200 Subject: SfxItemPool: detect duplicate SlotId mappings ... to prevent problems like fdo#66827. Sadly the EditEngineItemPool has loads of duplicate slotids already... Change-Id: I737d71519ce4af06c81f7ecf183cfa6c367026db --- include/svl/itempool.hxx | 3 +-- svl/source/items/itempool.cxx | 55 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx index b50bcb2836a6..6eddcbad8c1c 100644 --- a/include/svl/itempool.hxx +++ b/include/svl/itempool.hxx @@ -213,8 +213,7 @@ public: bool IsItemFlag( sal_uInt16 nWhich, sal_uInt16 nFlag ) const; bool IsItemFlag( const SfxPoolItem &rItem, sal_uInt16 nFlag ) const { return IsItemFlag( rItem.Which(), nFlag ); } - void SetItemInfos( const SfxItemInfo *pInfos ) - { pItemInfos = pInfos; } + void SetItemInfos( const SfxItemInfo *pInfos ); sal_uInt16 GetWhich( sal_uInt16 nSlot, sal_Bool bDeep = sal_True ) const; sal_uInt16 GetSlotId( sal_uInt16 nWhich, sal_Bool bDeep = sal_True ) const; sal_uInt16 GetTrueWhich( sal_uInt16 nSlot, sal_Bool bDeep = sal_True ) const; diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx index 50e47cb90b76..83e2e12655ab 100644 --- a/svl/source/items/itempool.cxx +++ b/svl/source/items/itempool.cxx @@ -28,6 +28,53 @@ #include "poolio.hxx" +#if OSL_DEBUG_LEVEL > 0 +#include + +static void +lcl_CheckSlots2(std::map & rSlotMap, + SfxItemPool const& rPool, SfxItemInfo const* pInfos) +{ + if (!pInfos) + return; // may not be initialized yet + if (rPool.GetName() == "EditEngineItemPool") + return; // HACK: this one has loads of duplicates already, ignore it :( + sal_uInt16 const nFirst(rPool.GetFirstWhich()); + sal_uInt16 const nCount(rPool.GetLastWhich() - rPool.GetFirstWhich() + 1); + for (sal_uInt16 n = 0; n < nCount; ++n) + { + sal_uInt16 const nSlotId(pInfos[n]._nSID); + if (nSlotId != 0 + && nSlotId != 10883 // preexisting duplicate SID_ATTR_GRAF_CROP + && nSlotId != 10024) // preexisting duplicate SID_ATTR_BORDER_OUTER + { // check for duplicate slot-id mapping + std::map::const_iterator const iter( + rSlotMap.find(nSlotId)); + sal_uInt16 const nWhich(nFirst + n); + if (iter != rSlotMap.end()) + { + SAL_WARN("svl", "SfxItemPool: duplicate SlotId " << nSlotId + << " mapped to " << iter->second << " and " << nWhich); + assert(false); + } + rSlotMap.insert(std::make_pair(nSlotId, nWhich)); + } + } +} + +#define CHECK_SLOTS() \ +do { \ + std::map slotmap; \ + for (SfxItemPool * p = pImp->mpMaster; p; p = p->pImp->mpSecondary) \ + { \ + lcl_CheckSlots2(slotmap, *p, p->pItemInfos); \ + } \ +} while (false) + +#else +#define CHECK_SLOTS() do {} while (false) +#endif + void SfxItemPool::AddSfxItemPoolUser(SfxItemPoolUser& rNewUser) { @@ -433,6 +480,14 @@ void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool ) // neuen Secondary-Pool merken pImp->mpSecondary = pPool; + + CHECK_SLOTS(); +} + +void SfxItemPool::SetItemInfos(SfxItemInfo const*const pInfos) +{ + pItemInfos = pInfos; + CHECK_SLOTS(); } // ----------------------------------------------------------------------- -- cgit