Kaydet (Commit) 7c3abee2 authored tarafından Caolán McNamara's avatar Caolán McNamara

Resolves: tdf#89643 report builder function wizard segfaults

regression from

    commit 3d652128
    CommitDate: Thu Jul 31 22:14:25 2014 +0200

        fix memory leak around function descriptions

        Found by Lsan.

There are two implementations of getCategory, one (sc) returns a new one each
time (hence the leak fix) and the other (reportdesign) returns a pointer to one
that belongs to the manger (hence the crash).

The code in formula really looks to me to expect that the getCategory return a
pointer that "someone else" needs to look after, i.e. the reportdesign variant
is the more correct so revert 3d652128 and to
fix the leak make the sc own the ScFunctionCategories and just cache them like
the reportdesign one does

Change-Id: Ifd986301a54b4d20449e864697655cd973e0c4df
üst 19053e62
......@@ -23,8 +23,6 @@
#include <unotools/charclass.hxx>
#include <unotools/syslocale.hxx>
#include <boost/scoped_ptr.hpp>
namespace formula
{
......@@ -95,7 +93,7 @@ bool FormulaHelper::GetNextFunc( const OUString& rFormula,
const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount();
for(sal_uInt32 j= 0; j < nCategoryCount && !*ppFDesc; ++j)
{
boost::scoped_ptr<const IFunctionCategory> pCategory(m_pFunctionManager->getCategory(j));
const IFunctionCategory* pCategory = m_pFunctionManager->getCategory(j);
const sal_uInt32 nCount = pCategory->getCount();
for(sal_uInt32 i = 0 ; i < nCount; ++i)
{
......
......@@ -60,7 +60,7 @@ namespace formula
~IFunctionManager() {}
};
class IFunctionCategory
class SAL_NO_VTABLE IFunctionCategory
{
public:
IFunctionCategory(){}
......@@ -70,7 +70,8 @@ namespace formula
virtual sal_uInt32 getNumber() const = 0;
virtual OUString getName() const = 0;
virtual ~IFunctionCategory() {}
protected:
~IFunctionCategory() {}
};
class SAL_NO_VTABLE IFunctionDescription
......
......@@ -27,6 +27,7 @@
#include <formula/IFunctionDescription.hxx>
#include <sal/types.h>
#include <rtl/ustring.hxx>
#include <map>
#define MAX_FUNCCAT 12 /* maximum number of categories for functions */
#define LRU_MAX 10 /* maximal number of last recently used functions */
......@@ -361,7 +362,7 @@ public:
/**
Returns a category.
Creates an IFunctionCategory object from a category specified by nPos.
Returns an IFunctionCategory object for a category specified by nPos.
@param nPos
the index of the category, note that 0 maps to the first category not the cumulative ('All') category.
......@@ -399,9 +400,10 @@ public:
private:
ScFunctionList* pFuncList; /**< list of all calc functions */
::std::vector<const ScFuncDesc*>* aCatLists[MAX_FUNCCAT]; /**< array of all categories, 0 is the cumulative ('All') category */
mutable ::std::vector<const ScFuncDesc*>::iterator pCurCatListIter; /**< position in current category */
mutable ::std::vector<const ScFuncDesc*>::iterator pCurCatListEnd; /**< end of current category */
std::vector<const ScFuncDesc*>* aCatLists[MAX_FUNCCAT]; /**< array of all categories, 0 is the cumulative ('All') category */
mutable std::map< sal_uInt32, std::shared_ptr<ScFunctionCategory> > m_aCategories; /**< map of category pos to IFunctionCategory */
mutable std::vector<const ScFuncDesc*>::iterator pCurCatListIter; /**< position in current category */
mutable std::vector<const ScFuncDesc*>::iterator pCurCatListEnd; /**< end of current category */
};
#endif // INCLUDED_SC_INC_FUNCDESC_HXX
......
......@@ -752,12 +752,13 @@ sal_uInt32 ScFunctionMgr::getCount() const
const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const
{
formula::IFunctionCategory* pRet = NULL;
if ( nCategory < (MAX_FUNCCAT-1) )
{
pRet = new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all"
if (m_aCategories.find(nCategory) == m_aCategories.end())
m_aCategories[nCategory].reset(new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory)); // aCatLists[0] is "all"
return m_aCategories[nCategory].get();
}
return pRet;
return NULL;
}
const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const OUString& _sFunctionName) const
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment