Fix memory leak in wxXmlNode::operator=().
We must delete all children and attributes in the node being overwritten and not just the first one of each. Add a unit test exercising this code to be able to check that valgrind doesn't report memory leak any more after the fix. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73990 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -216,6 +216,7 @@ private:
|
|||||||
int m_lineNo; // line number in original file, or -1
|
int m_lineNo; // line number in original file, or -1
|
||||||
bool m_noConversion; // don't do encoding conversion - node is plain text
|
bool m_noConversion; // don't do encoding conversion - node is plain text
|
||||||
|
|
||||||
|
void DoFree();
|
||||||
void DoCopy(const wxXmlNode& node);
|
void DoCopy(const wxXmlNode& node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -91,6 +91,18 @@ wxXmlNode::wxXmlNode(const wxXmlNode& node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wxXmlNode::~wxXmlNode()
|
wxXmlNode::~wxXmlNode()
|
||||||
|
{
|
||||||
|
DoFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
|
||||||
|
{
|
||||||
|
DoFree();
|
||||||
|
DoCopy(node);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxXmlNode::DoFree()
|
||||||
{
|
{
|
||||||
wxXmlNode *c, *c2;
|
wxXmlNode *c, *c2;
|
||||||
for (c = m_children; c; c = c2)
|
for (c = m_children; c; c = c2)
|
||||||
@@ -107,14 +119,6 @@ wxXmlNode::~wxXmlNode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
|
|
||||||
{
|
|
||||||
wxDELETE(m_attrs);
|
|
||||||
wxDELETE(m_children);
|
|
||||||
DoCopy(node);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxXmlNode::DoCopy(const wxXmlNode& node)
|
void wxXmlNode::DoCopy(const wxXmlNode& node)
|
||||||
{
|
{
|
||||||
m_type = node.m_type;
|
m_type = node.m_type;
|
||||||
|
@@ -82,6 +82,7 @@ private:
|
|||||||
CPPUNIT_TEST( DetachRoot );
|
CPPUNIT_TEST( DetachRoot );
|
||||||
CPPUNIT_TEST( AppendToProlog );
|
CPPUNIT_TEST( AppendToProlog );
|
||||||
CPPUNIT_TEST( SetRoot );
|
CPPUNIT_TEST( SetRoot );
|
||||||
|
CPPUNIT_TEST( CopyNode );
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
void InsertChild();
|
void InsertChild();
|
||||||
@@ -93,6 +94,7 @@ private:
|
|||||||
void DetachRoot();
|
void DetachRoot();
|
||||||
void AppendToProlog();
|
void AppendToProlog();
|
||||||
void SetRoot();
|
void SetRoot();
|
||||||
|
void CopyNode();
|
||||||
|
|
||||||
DECLARE_NO_COPY_CLASS(XmlTestCase)
|
DECLARE_NO_COPY_CLASS(XmlTestCase)
|
||||||
};
|
};
|
||||||
@@ -469,3 +471,40 @@ void XmlTestCase::SetRoot()
|
|||||||
doc.SetRoot(root);
|
doc.SetRoot(root);
|
||||||
CPPUNIT_ASSERT( doc.IsOk() );
|
CPPUNIT_ASSERT( doc.IsOk() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XmlTestCase::CopyNode()
|
||||||
|
{
|
||||||
|
const char *xmlText =
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<root>\n"
|
||||||
|
" <first><sub1/><sub2/><sub3/></first>\n"
|
||||||
|
" <second/>\n"
|
||||||
|
"</root>\n"
|
||||||
|
;
|
||||||
|
wxXmlDocument doc;
|
||||||
|
wxStringInputStream sis(xmlText);
|
||||||
|
CPPUNIT_ASSERT( doc.Load(sis) );
|
||||||
|
|
||||||
|
wxXmlNode* const root = doc.GetRoot();
|
||||||
|
CPPUNIT_ASSERT( root );
|
||||||
|
|
||||||
|
wxXmlNode* const first = root->GetChildren();
|
||||||
|
CPPUNIT_ASSERT( first );
|
||||||
|
|
||||||
|
wxXmlNode* const second = first->GetNext();
|
||||||
|
CPPUNIT_ASSERT( second );
|
||||||
|
|
||||||
|
*first = *second;
|
||||||
|
|
||||||
|
wxStringOutputStream sos;
|
||||||
|
CPPUNIT_ASSERT( doc.Save(sos) );
|
||||||
|
|
||||||
|
const char *xmlTextResult =
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<root>\n"
|
||||||
|
" <second/>\n"
|
||||||
|
" <second/>\n"
|
||||||
|
"</root>\n"
|
||||||
|
;
|
||||||
|
CPPUNIT_ASSERT_EQUAL( xmlTextResult, sos.GetString() );
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user