From: Vadim Zeitlin Date: Wed, 15 May 2013 20:01:58 +0000 (+0000) Subject: Fix memory leak in wxXmlNode::operator=(). X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/0b3e395a5c7a61c6bcf08e2c340a7f2de8ba3c37 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 --- diff --git a/include/wx/xml/xml.h b/include/wx/xml/xml.h index fbd6faa4ac..5bbe006366 100644 --- a/include/wx/xml/xml.h +++ b/include/wx/xml/xml.h @@ -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); }; diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index ee78a9aca4..6e2dbf6c96 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -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; diff --git a/tests/xml/xmltest.cpp b/tests/xml/xmltest.cpp index ee41451a38..ce807b607e 100644 --- a/tests/xml/xmltest.cpp +++ b/tests/xml/xmltest.cpp @@ -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 = +"\n" +"\n" +" \n" +" \n" +"\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 = +"\n" +"\n" +" \n" +" \n" +"\n" + ; + CPPUNIT_ASSERT_EQUAL( xmlTextResult, sos.GetString() ); +}