]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix memory leak in wxXmlNode::operator=().
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 15 May 2013 20:01:58 +0000 (20:01 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 15 May 2013 20:01:58 +0000 (20:01 +0000)
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

include/wx/xml/xml.h
src/xml/xml.cpp
tests/xml/xmltest.cpp

index fbd6faa4acaff834915885277c0a0f985df84167..5bbe006366b7c03fe39d2a9fdcd71dfa9e0422f3 100644 (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);
 };
 
index ee78a9aca4a2da3a414c55c61ae1645de6a1f2b8..6e2dbf6c96d0cc0aa59cbcb60be547c64ceb59dd 100644 (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;
index ee41451a3801f303005645784ce8040bab990a46..ce807b607e54d220d8499a4c39f03e39cc8700da 100644 (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() );
+}