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:
Vadim Zeitlin
2013-05-15 20:01:58 +00:00
parent 5181927e6b
commit 0b3e395a5c
3 changed files with 52 additions and 8 deletions

View File

@@ -216,6 +216,7 @@ private:
int m_lineNo; // line number in original file, or -1
bool m_noConversion; // don't do encoding conversion - node is plain text
void DoFree();
void DoCopy(const wxXmlNode& node);
};

View File

@@ -91,6 +91,18 @@ wxXmlNode::wxXmlNode(const wxXmlNode& node)
}
wxXmlNode::~wxXmlNode()
{
DoFree();
}
wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
{
DoFree();
DoCopy(node);
return *this;
}
void wxXmlNode::DoFree()
{
wxXmlNode *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)
{
m_type = node.m_type;

View File

@@ -82,6 +82,7 @@ private:
CPPUNIT_TEST( DetachRoot );
CPPUNIT_TEST( AppendToProlog );
CPPUNIT_TEST( SetRoot );
CPPUNIT_TEST( CopyNode );
CPPUNIT_TEST_SUITE_END();
void InsertChild();
@@ -93,6 +94,7 @@ private:
void DetachRoot();
void AppendToProlog();
void SetRoot();
void CopyNode();
DECLARE_NO_COPY_CLASS(XmlTestCase)
};
@@ -469,3 +471,40 @@ void XmlTestCase::SetRoot()
doc.SetRoot(root);
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() );
}