[ekiga/gnome-2-26] Fixed bug #576324 (unsafely shared xmlDoc pointers)



commit abd0fd9facd676a39d6c0fabec41e29cae1899b6
Author: Julien Puydt <jpuydt src gnome org>
Date:   Mon Mar 23 22:14:27 2009 +0000

    Fixed bug #576324 (unsafely shared xmlDoc pointers)
    
    svn path=/trunk/; revision=7805
---
 .../components/call-history/history-book.cpp       |   39 +++++++++-----------
 lib/engine/components/call-history/history-book.h  |    4 +--
 .../components/call-history/history-contact.cpp    |    6 ++-
 .../components/call-history/history-contact.h      |    5 +++
 lib/engine/components/ldap/ldap-book.cpp           |    6 ++-
 lib/engine/components/ldap/ldap-book.h             |    4 ++
 lib/engine/components/ldap/ldap-source.cpp         |   30 +++++++--------
 lib/engine/components/ldap/ldap-source.h           |    2 +-
 lib/engine/components/local-roster/local-heap.cpp  |   30 ++++++++--------
 lib/engine/components/local-roster/local-heap.h    |    4 +--
 .../components/local-roster/local-presentity.cpp   |    6 ++-
 .../components/local-roster/local-presentity.h     |    9 ++++-
 lib/engine/components/resource-list/rl-cluster.cpp |   28 +++++++-------
 lib/engine/components/resource-list/rl-cluster.h   |    2 +-
 lib/engine/components/resource-list/rl-entry.cpp   |   16 ++++----
 lib/engine/components/resource-list/rl-entry.h     |    5 ++-
 lib/engine/components/resource-list/rl-heap.cpp    |   36 +++++++++----------
 lib/engine/components/resource-list/rl-heap.h      |    4 ++-
 lib/engine/components/resource-list/rl-list.cpp    |   18 ++++-----
 .../components/resource-list/rl-presentity.cpp     |    7 ++--
 .../components/resource-list/rl-presentity.h       |    3 ++
 21 files changed, 140 insertions(+), 124 deletions(-)

diff --git a/lib/engine/components/call-history/history-book.cpp b/lib/engine/components/call-history/history-book.cpp
index 84993df..f52f795 100644
--- a/lib/engine/components/call-history/history-book.cpp
+++ b/lib/engine/components/call-history/history-book.cpp
@@ -48,7 +48,7 @@
 #define KEY "/apps/" PACKAGE_NAME "/contacts/call_history"
 
 History::Book::Book (Ekiga::ServiceCore &_core) :
-  core(_core), doc(NULL)
+  core(_core), doc()
 {
   xmlNodePtr root = NULL;
 
@@ -58,16 +58,15 @@ History::Book::Book (Ekiga::ServiceCore &_core) :
 
     const std::string raw = c_raw;
 
-    doc = xmlRecoverMemory (raw.c_str (), raw.length ());
-    if (doc == NULL)
-      doc = xmlNewDoc (BAD_CAST "1.0");
-
-    root = xmlDocGetRootElement (doc);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlRecoverMemory (raw.c_str (), raw.length ()), xmlFreeDoc);
+    if ( !doc)
+      doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
 
+    root = xmlDocGetRootElement (doc.get ());
     if (root == NULL) {
 
-      root = xmlNewNode (NULL, BAD_CAST "list");
-      xmlDocSetRootElement (doc, root);
+      root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+      xmlDocSetRootElement (doc.get (), root);
     }
 
     for (xmlNodePtr child = root->children;
@@ -81,9 +80,9 @@ History::Book::Book (Ekiga::ServiceCore &_core) :
     g_free (c_raw);
   } else {
 
-    doc = xmlNewDoc (BAD_CAST "1.0");
-    root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
-    xmlDocSetRootElement (doc, root);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+    root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+    xmlDocSetRootElement (doc.get (), root);
   }
 
   gmref_ptr<Ekiga::CallCore> call_core = core.get ("call-core");
@@ -94,8 +93,6 @@ History::Book::Book (Ekiga::ServiceCore &_core) :
 
 History::Book::~Book ()
 {
-  if (doc != NULL)
-    xmlFreeDoc (doc);
 }
 
 const std::string
@@ -107,7 +104,7 @@ History::Book::get_name () const
 void
 History::Book::add (xmlNodePtr node)
 {
-  add_contact (gmref_ptr<Contact>(new Contact (core, node)));
+  add_contact (gmref_ptr<Contact>(new Contact (core, doc, node)));
 }
 
 void
@@ -120,9 +117,9 @@ History::Book::add (const std::string & name,
 
   if ( !uri.empty ()) {
 
-    xmlNodePtr root = xmlDocGetRootElement (doc);
+    xmlNodePtr root = xmlDocGetRootElement (doc.get ());
 
-    gmref_ptr<Contact> contact(new Contact (core, name, uri,
+    gmref_ptr<Contact> contact(new Contact (core, doc, name, uri,
 					    call_start, call_duration, c_t));
 
     xmlAddChild (root, contact->get_node ());
@@ -165,7 +162,7 @@ History::Book::save () const
   xmlChar *buffer = NULL;
   int size = 0;
 
-  xmlDocDumpMemory (doc, &buffer, &size);
+  xmlDocDumpMemory (doc.get (), &buffer, &size);
 
   gm_conf_set_string (KEY, (const char *)buffer);
 
@@ -179,11 +176,9 @@ History::Book::clear ()
 
   remove_all_objects ();
 
-  if (doc != NULL)
-    xmlFreeDoc (doc);
-  doc = xmlNewDoc (BAD_CAST "1.0");
-  root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
-  xmlDocSetRootElement (doc, root);
+  doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+  root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+  xmlDocSetRootElement (doc.get (), root);
 
   save ();
   cleared.emit ();
diff --git a/lib/engine/components/call-history/history-book.h b/lib/engine/components/call-history/history-book.h
index c1cd9f5..8c471b3 100644
--- a/lib/engine/components/call-history/history-book.h
+++ b/lib/engine/components/call-history/history-book.h
@@ -36,8 +36,6 @@
 #ifndef __HISTORY_BOOK_H__
 #define __HISTORY_BOOK_H__
 
-#include <libxml/tree.h>
-
 #include "call-core.h"
 #include "call-manager.h"
 
@@ -107,7 +105,7 @@ namespace History
 			  std::string message);
 
     Ekiga::ServiceCore &core;
-    xmlDocPtr doc;
+    std::tr1::shared_ptr<xmlDoc> doc;
   };
 
 /**
diff --git a/lib/engine/components/call-history/history-contact.cpp b/lib/engine/components/call-history/history-contact.cpp
index 545e618..1829a1c 100644
--- a/lib/engine/components/call-history/history-contact.cpp
+++ b/lib/engine/components/call-history/history-contact.cpp
@@ -45,8 +45,9 @@
 
 
 History::Contact::Contact (Ekiga::ServiceCore &_core,
+			   std::tr1::shared_ptr<xmlDoc> _doc,
 			   xmlNodePtr _node):
-  core(_core), node(_node)
+  core(_core), doc(_doc), node(_node)
 {
   xmlChar* xml_str = NULL;
   gmref_ptr<Ekiga::ContactCore> contact_core = core.get ("contact-core");
@@ -101,12 +102,13 @@ History::Contact::Contact (Ekiga::ServiceCore &_core,
 
 
 History::Contact::Contact (Ekiga::ServiceCore &_core,
+			   std::tr1::shared_ptr<xmlDoc> _doc,
 			   const std::string _name,
 			   const std::string _uri,
                            time_t _call_start,
                            const std::string _call_duration,
 			   call_type c_t):
-  core(_core), name(_name), uri(_uri), call_start(_call_start), call_duration(_call_duration), m_type(c_t)
+  core(_core), doc(_doc), name(_name), uri(_uri), call_start(_call_start), call_duration(_call_duration), m_type(c_t)
 {
   gchar* tmp = NULL;
   std::string callp;
diff --git a/lib/engine/components/call-history/history-contact.h b/lib/engine/components/call-history/history-contact.h
index 794606d..efeffd1 100644
--- a/lib/engine/components/call-history/history-contact.h
+++ b/lib/engine/components/call-history/history-contact.h
@@ -38,6 +38,8 @@
 
 #include <libxml/tree.h>
 
+#include <tr1/memory>
+
 #include "services.h"
 #include "contact-core.h"
 
@@ -62,9 +64,11 @@ namespace History
   public:
 
     Contact (Ekiga::ServiceCore &_core,
+	     std::tr1::shared_ptr<xmlDoc> _doc,
 	     xmlNodePtr _node);
 
     Contact (Ekiga::ServiceCore &_core,
+	     std::tr1::shared_ptr<xmlDoc> _doc,
 	     const std::string _name,
 	     const std::string _uri,
              time_t call_start,
@@ -97,6 +101,7 @@ namespace History
 
     Ekiga::ServiceCore &core;
 
+    std::tr1::shared_ptr<xmlDoc> doc;
     xmlNodePtr node;
     std::string name;
     std::string uri;
diff --git a/lib/engine/components/ldap/ldap-book.cpp b/lib/engine/components/ldap/ldap-book.cpp
index 7e64868..3833442 100644
--- a/lib/engine/components/ldap/ldap-book.cpp
+++ b/lib/engine/components/ldap/ldap-book.cpp
@@ -166,8 +166,9 @@ struct RefreshData
 /* actual implementation */
 
 OPENLDAP::Book::Book (Ekiga::ServiceCore &_core,
+		      std::tr1::shared_ptr<xmlDoc> _doc,
 		      xmlNodePtr _node):
-  saslform(NULL), core(_core), node(_node),
+  saslform(NULL), core(_core), doc(_doc), node(_node),
   name_node(NULL), uri_node(NULL), authcID_node(NULL), password_node(NULL),
   ldap_context(NULL), patience(0)
 {
@@ -334,8 +335,9 @@ OPENLDAP::Book::Book (Ekiga::ServiceCore &_core,
 }
 
 OPENLDAP::Book::Book (Ekiga::ServiceCore &_core,
+		      std::tr1::shared_ptr<xmlDoc> _doc,
 		      OPENLDAP::BookInfo _bookinfo):
-  saslform(NULL), core(_core), name_node(NULL),
+  saslform(NULL), core(_core), doc(_doc), name_node(NULL),
   uri_node(NULL), authcID_node(NULL), password_node(NULL),
   ldap_context(NULL), patience(0)
 {
diff --git a/lib/engine/components/ldap/ldap-book.h b/lib/engine/components/ldap/ldap-book.h
index 4cdeb95..0d6a154 100644
--- a/lib/engine/components/ldap/ldap-book.h
+++ b/lib/engine/components/ldap/ldap-book.h
@@ -40,6 +40,7 @@
 #define __LDAP_BOOK_H__
 
 #include <vector>
+#include <tr1/memory>
 #include <libxml/tree.h>
 #include <glib/gi18n.h>
 
@@ -87,9 +88,11 @@ namespace OPENLDAP
   public:
 
     Book (Ekiga::ServiceCore &_core,
+	  std::tr1::shared_ptr<xmlDoc> _doc,
 	  xmlNodePtr node);
 
     Book (Ekiga::ServiceCore &_core,
+	  std::tr1::shared_ptr<xmlDoc> _doc,
     	  OPENLDAP::BookInfo _bookinfo);
 
     ~Book ();
@@ -132,6 +135,7 @@ namespace OPENLDAP
 				 Ekiga::Form &form);
 
     Ekiga::ServiceCore &core;
+    std::tr1::shared_ptr<xmlDoc> doc;
     xmlNodePtr node;
 
     xmlNodePtr name_node;
diff --git a/lib/engine/components/ldap/ldap-source.cpp b/lib/engine/components/ldap/ldap-source.cpp
index 06b8fcb..e0929cf 100644
--- a/lib/engine/components/ldap/ldap-source.cpp
+++ b/lib/engine/components/ldap/ldap-source.cpp
@@ -48,7 +48,7 @@
 
 #define KEY "/apps/" PACKAGE_NAME "/contacts/ldap_servers"
 
-OPENLDAP::Source::Source (Ekiga::ServiceCore &_core): core(_core), doc(NULL)
+OPENLDAP::Source::Source (Ekiga::ServiceCore &_core): core(_core), doc()
 {
   xmlNodePtr root;
   gchar *c_raw = gm_conf_get_string (KEY);
@@ -57,16 +57,16 @@ OPENLDAP::Source::Source (Ekiga::ServiceCore &_core): core(_core), doc(NULL)
 
     const std::string raw = c_raw;
 
-    doc = xmlRecoverMemory (raw.c_str (), raw.length ());
-    if (doc == NULL)
-      doc = xmlNewDoc (BAD_CAST "1.0");
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlRecoverMemory (raw.c_str (), raw.length ()), xmlFreeDoc);
+    if ( !doc)
+      doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
 
-    root = xmlDocGetRootElement (doc);
+    root = xmlDocGetRootElement (doc.get ());
 
     if (root == NULL) {
 
-      root = xmlNewNode (NULL, BAD_CAST "list");
-      xmlDocSetRootElement (doc, root);
+      root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+      xmlDocSetRootElement (doc.get (), root);
     }
 
     for (xmlNodePtr child = root->children ;
@@ -80,9 +80,9 @@ OPENLDAP::Source::Source (Ekiga::ServiceCore &_core): core(_core), doc(NULL)
     g_free (c_raw);
   } else {
 
-    doc = xmlNewDoc (BAD_CAST "1.0");
-    root = xmlNewNode (NULL, BAD_CAST "list");
-    xmlDocSetRootElement (doc, root);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+    root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+    xmlDocSetRootElement (doc.get (), root);
 
     new_ekiga_net_book ();
   }
@@ -90,14 +90,12 @@ OPENLDAP::Source::Source (Ekiga::ServiceCore &_core): core(_core), doc(NULL)
 
 OPENLDAP::Source::~Source ()
 {
-  if (doc)
-    xmlFreeDoc (doc);
 }
 
 void
 OPENLDAP::Source::add (xmlNodePtr node)
 {
-  common_add (gmref_ptr<Book>(new Book (core, node)));
+  common_add (gmref_ptr<Book>(new Book (core, doc, node)));
 }
 
 void
@@ -105,8 +103,8 @@ OPENLDAP::Source::add ()
 {
   xmlNodePtr root;
 
-  root = xmlDocGetRootElement (doc);
-  gmref_ptr<Book> book (new Book (core, bookinfo));
+  root = xmlDocGetRootElement (doc.get ());
+  gmref_ptr<Book> book (new Book (core, doc, bookinfo));
 
   xmlAddChild (root, book->get_node ());
 
@@ -216,7 +214,7 @@ OPENLDAP::Source::save ()
   xmlChar *buffer = NULL;
   int size = 0;
 
-  xmlDocDumpMemory (doc, &buffer, &size);
+  xmlDocDumpMemory (doc.get (), &buffer, &size);
 
   gm_conf_set_string (KEY, (const char *)buffer);
 
diff --git a/lib/engine/components/ldap/ldap-source.h b/lib/engine/components/ldap/ldap-source.h
index 3c1fb3d..b86e646 100644
--- a/lib/engine/components/ldap/ldap-source.h
+++ b/lib/engine/components/ldap/ldap-source.h
@@ -76,7 +76,7 @@ namespace OPENLDAP
   private:
 
     Ekiga::ServiceCore &core;
-    xmlDocPtr doc;
+    std::tr1::shared_ptr<xmlDoc> doc;
 
     struct BookInfo bookinfo;
 
diff --git a/lib/engine/components/local-roster/local-heap.cpp b/lib/engine/components/local-roster/local-heap.cpp
index 0e0327b..f590dfb 100644
--- a/lib/engine/components/local-roster/local-heap.cpp
+++ b/lib/engine/components/local-roster/local-heap.cpp
@@ -51,7 +51,7 @@
 /*
  * Public API
  */
-Local::Heap::Heap (Ekiga::ServiceCore &_core): core (_core), doc (NULL)
+Local::Heap::Heap (Ekiga::ServiceCore &_core): core (_core), doc ()
 {
   xmlNodePtr root;
   gchar *c_raw = gm_conf_get_string (KEY);
@@ -60,13 +60,15 @@ Local::Heap::Heap (Ekiga::ServiceCore &_core): core (_core), doc (NULL)
   if (c_raw != NULL) {
 
     const std::string raw = c_raw;
-    doc = xmlRecoverMemory (raw.c_str (), raw.length ());
-
-    root = xmlDocGetRootElement (doc);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlRecoverMemory (raw.c_str (), raw.length ()), xmlFreeDoc);
+    if ( !doc)
+      doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+    
+    root = xmlDocGetRootElement (doc.get ());
     if (root == NULL) {
 
-      root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
-      xmlDocSetRootElement (doc, root);
+      root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+      xmlDocSetRootElement (doc.get (), root);
     }
 
     for (xmlNodePtr child = root->children; child != NULL; child = child->next)
@@ -81,9 +83,9 @@ Local::Heap::Heap (Ekiga::ServiceCore &_core): core (_core), doc (NULL)
   }
   else {
 
-    doc = xmlNewDoc (BAD_CAST "1.0");
-    root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
-    xmlDocSetRootElement (doc, root);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+    root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+    xmlDocSetRootElement (doc.get (), root);
 
     {
       // add 500 and 501 at ekiga.net in this case!
@@ -99,8 +101,6 @@ Local::Heap::Heap (Ekiga::ServiceCore &_core): core (_core), doc (NULL)
 
 Local::Heap::~Heap ()
 {
-  if (doc != NULL)
-    xmlFreeDoc (doc);
 }
 
 
@@ -245,7 +245,7 @@ Local::Heap::push_status (const std::string uri,
 void
 Local::Heap::add (xmlNodePtr node)
 {
-  gmref_ptr<Presentity> presentity (new Presentity (core, node));
+  gmref_ptr<Presentity> presentity (new Presentity (core, doc, node));
 
   common_add (presentity);
 }
@@ -258,8 +258,8 @@ Local::Heap::add (const std::string name,
 {
   xmlNodePtr root = NULL;
 
-  root = xmlDocGetRootElement (doc);
-  gmref_ptr<Presentity> presentity (new Presentity (core, name, uri, groups));
+  root = xmlDocGetRootElement (doc.get ());
+  gmref_ptr<Presentity> presentity (new Presentity (core, doc, name, uri, groups));
 
   xmlAddChild (root, presentity->get_node ());
 
@@ -290,7 +290,7 @@ Local::Heap::save () const
   xmlChar *buffer = NULL;
   int size = 0;
 
-  xmlDocDumpMemory (doc, &buffer, &size);
+  xmlDocDumpMemory (doc.get (), &buffer, &size);
 
   gm_conf_set_string (KEY, (const char *)buffer);
 
diff --git a/lib/engine/components/local-roster/local-heap.h b/lib/engine/components/local-roster/local-heap.h
index cea4cbf..e9302d8 100644
--- a/lib/engine/components/local-roster/local-heap.h
+++ b/lib/engine/components/local-roster/local-heap.h
@@ -37,8 +37,6 @@
 #ifndef __LOCAL_HEAP_H__
 #define __LOCAL_HEAP_H__
 
-#include <libxml/tree.h>
-
 #include "heap-impl.h"
 #include "local-presentity.h"
 
@@ -201,7 +199,7 @@ namespace Local
 				      Ekiga::Form& result);
 
     Ekiga::ServiceCore &core;
-    xmlDocPtr doc;
+    std::tr1::shared_ptr<xmlDoc> doc;
   };
 
 /**
diff --git a/lib/engine/components/local-roster/local-presentity.cpp b/lib/engine/components/local-roster/local-presentity.cpp
index 2c11381..0efcf15 100644
--- a/lib/engine/components/local-roster/local-presentity.cpp
+++ b/lib/engine/components/local-roster/local-presentity.cpp
@@ -48,8 +48,9 @@
  * Public API
  */
 Local::Presentity::Presentity (Ekiga::ServiceCore &_core,
+			       std::tr1::shared_ptr<xmlDoc> _doc,
 			       xmlNodePtr _node) :
-  core(_core), node(_node), name_node(NULL), presence("unknown")
+  core(_core), doc(_doc), node(_node), name_node(NULL), presence("unknown")
 {
   xmlChar *xml_str = NULL;
 
@@ -97,10 +98,11 @@ Local::Presentity::Presentity (Ekiga::ServiceCore &_core,
 
 
 Local::Presentity::Presentity (Ekiga::ServiceCore &_core,
+			       std::tr1::shared_ptr<xmlDoc> _doc,
 			       const std::string _name,
 			       const std::string _uri,
 			       const std::set<std::string> _groups) :
-  core(_core), name_node(NULL), name(_name), uri(_uri),
+  core(_core), doc(_doc), name_node(NULL), name(_name), uri(_uri),
   presence("unknown"), groups(_groups)
 {
   node = xmlNewNode (NULL, BAD_CAST "entry");
diff --git a/lib/engine/components/local-roster/local-presentity.h b/lib/engine/components/local-roster/local-presentity.h
index a950a15..80378c2 100644
--- a/lib/engine/components/local-roster/local-presentity.h
+++ b/lib/engine/components/local-roster/local-presentity.h
@@ -38,11 +38,15 @@
 #ifndef __LOCAL_PRESENTITY_H__
 #define __LOCAL_PRESENTITY_H__
 
+#include <libxml/tree.h>
+
+#include <tr1/memory>
+
+
 #include "form.h"
 #include "presence-core.h"
 #include "presentity.h"
 
-
 namespace Local
 {
 
@@ -69,9 +73,11 @@ namespace Local
      * Constructors (and destructor)
      */
     Presentity (Ekiga::ServiceCore &_core,
+		std::tr1::shared_ptr<xmlDoc> _doc,
 		xmlNodePtr _node);
 
     Presentity (Ekiga::ServiceCore &_core,
+		std::tr1::shared_ptr<xmlDoc> _doc,
 		const std::string _name,
 		const std::string _uri,
 		const std::set<std::string> _groups);
@@ -173,6 +179,7 @@ namespace Local
 
     Ekiga::ServiceCore &core;
 
+    std::tr1::shared_ptr<xmlDoc> doc;
     xmlNodePtr node;
     xmlNodePtr name_node;
 
diff --git a/lib/engine/components/resource-list/rl-cluster.cpp b/lib/engine/components/resource-list/rl-cluster.cpp
index 3685172..337768f 100644
--- a/lib/engine/components/resource-list/rl-cluster.cpp
+++ b/lib/engine/components/resource-list/rl-cluster.cpp
@@ -48,7 +48,7 @@
 
 #define KEY "/apps/" PACKAGE_NAME "/contacts/resource-lists"
 
-RL::Cluster::Cluster (Ekiga::ServiceCore& core_): core(core_), doc(NULL)
+RL::Cluster::Cluster (Ekiga::ServiceCore& core_): core(core_), doc()
 {
   gchar* c_raw = NULL;
 
@@ -62,13 +62,15 @@ RL::Cluster::Cluster (Ekiga::ServiceCore& core_): core(core_), doc(NULL)
   if (c_raw != NULL) {
 
     const std::string raw = c_raw;
-    doc = xmlRecoverMemory (raw.c_str (), raw.length ());
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlRecoverMemory (raw.c_str (), raw.length ()), xmlFreeDoc);
+    if ( !doc)
+      doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
 
-    xmlNodePtr root = xmlDocGetRootElement (doc);
+    xmlNodePtr root = xmlDocGetRootElement (doc.get ());
     if (root == NULL) {
 
-      root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
-      xmlDocSetRootElement (doc, root);
+      root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+      xmlDocSetRootElement (doc.get (), root);
     } else {
 
       for (xmlNodePtr child = root->children;
@@ -83,17 +85,15 @@ RL::Cluster::Cluster (Ekiga::ServiceCore& core_): core(core_), doc(NULL)
 
   } else {
 
-    doc = xmlNewDoc (BAD_CAST "1.0");
-    xmlNodePtr root = xmlNewDocNode (doc, NULL, BAD_CAST "list", NULL);
-    xmlDocSetRootElement (doc, root);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+    xmlNodePtr root = xmlNewDocNode (doc.get (), NULL, BAD_CAST "list", NULL);
+    xmlDocSetRootElement (doc.get (), root);
     add ("https://xcap.sipthor.net/xcap-root";, "alice", "123", "alice example com", "XCAP Test", false); // FIXME: remove
   }
 }
 
 RL::Cluster::~Cluster ()
 {
-  if (doc != NULL)
-    xmlFreeDoc (doc);
 }
 
 bool
@@ -108,7 +108,7 @@ RL::Cluster::populate_menu (Ekiga::MenuBuilder& builder)
 void
 RL::Cluster::add (xmlNodePtr node)
 {
-  gmref_ptr<Heap> heap (new Heap (core, node));
+  gmref_ptr<Heap> heap (new Heap (core, doc, node));
 
   common_add (heap);
 }
@@ -121,8 +121,8 @@ RL::Cluster::add (const std::string uri,
 		  const std::string name,
 		  bool writable)
 {
-  gmref_ptr<Heap> heap (new Heap (core, name, uri, user, username, password, writable));
-  xmlNodePtr root = xmlDocGetRootElement (doc);
+  gmref_ptr<Heap> heap (new Heap (core, doc, name, uri, user, username, password, writable));
+  xmlNodePtr root = xmlDocGetRootElement (doc.get ());
 
   xmlAddChild (root, heap->get_node ());
 
@@ -146,7 +146,7 @@ RL::Cluster::save () const
   xmlChar* buffer = NULL;
   int size = 0;
 
-  xmlDocDumpMemory (doc, &buffer, &size);
+  xmlDocDumpMemory (doc.get (), &buffer, &size);
 
   gm_conf_set_string (KEY, (const char*)buffer);
 
diff --git a/lib/engine/components/resource-list/rl-cluster.h b/lib/engine/components/resource-list/rl-cluster.h
index 80b8f82..f3e3e81 100644
--- a/lib/engine/components/resource-list/rl-cluster.h
+++ b/lib/engine/components/resource-list/rl-cluster.h
@@ -65,7 +65,7 @@ namespace RL {
   private:
 
     Ekiga::ServiceCore& core;
-    xmlDocPtr doc;
+    std::tr1::shared_ptr<xmlDoc> doc;
 
     void add (xmlNodePtr node);
     void add (const std::string uri,
diff --git a/lib/engine/components/resource-list/rl-entry.cpp b/lib/engine/components/resource-list/rl-entry.cpp
index e32cec5..378b144 100644
--- a/lib/engine/components/resource-list/rl-entry.cpp
+++ b/lib/engine/components/resource-list/rl-entry.cpp
@@ -47,8 +47,9 @@ RL::Entry::Entry (Ekiga::ServiceCore& core_,
 		  gmref_ptr<XCAP::Path> path_,
 		  int pos,
 		  const std::string group,
+		  std::tr1::shared_ptr<xmlDoc> doc_,
 		  xmlNodePtr node_):
-  core(core_), position(pos), doc(NULL), node(node_), name_node(NULL),
+  core(core_), position(pos), doc(doc_), node(node_), name_node(NULL),
   presence("unknown"), status("")
 {
   groups.insert (group);
@@ -76,8 +77,6 @@ RL::Entry::Entry (Ekiga::ServiceCore& core_,
 
 RL::Entry::~Entry ()
 {
-  if (doc != NULL)
-    xmlFreeDoc (doc);
 }
 
 const std::string
@@ -155,9 +154,7 @@ RL::Entry::populate_menu (Ekiga::MenuBuilder& builder)
 void
 RL::Entry::refresh ()
 {
-  if (doc != NULL)
-    xmlFreeDoc (doc);
-  doc = NULL;
+  doc.reset ();
   node = NULL;
   name_node = NULL;
   presence = "unknown";
@@ -178,8 +175,11 @@ RL::Entry::on_xcap_answer (bool error,
 
   } else {
 
-    doc = xmlRecoverMemory (value.c_str (), value.length ());
-    node = xmlDocGetRootElement (doc);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlRecoverMemory (value.c_str (), value.length ()), xmlFreeDoc);
+    if ( !doc)
+      doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+
+    node = xmlDocGetRootElement (doc.get ());
     if (node == NULL
 	|| node->name == NULL
 	|| !xmlStrEqual (BAD_CAST "entry", node->name)) {
diff --git a/lib/engine/components/resource-list/rl-entry.h b/lib/engine/components/resource-list/rl-entry.h
index 4c59fa4..60dd474 100644
--- a/lib/engine/components/resource-list/rl-entry.h
+++ b/lib/engine/components/resource-list/rl-entry.h
@@ -44,6 +44,8 @@
 
 #include <libxml/tree.h>
 
+#include <tr1/memory>
+
 namespace RL {
 
   class Entry:
@@ -56,6 +58,7 @@ namespace RL {
 	   gmref_ptr<XCAP::Path> path_,
 	   int pos,
 	   const std::string group,
+	   std::tr1::shared_ptr<xmlDoc> doc_,
 	   xmlNodePtr node_);
 
     ~Entry ();
@@ -93,7 +96,7 @@ namespace RL {
 
     std::set<std::string> groups;
 
-    xmlDocPtr doc;
+    std::tr1::shared_ptr<xmlDoc> doc;
     xmlNodePtr node;
     xmlNodePtr name_node;
 
diff --git a/lib/engine/components/resource-list/rl-heap.cpp b/lib/engine/components/resource-list/rl-heap.cpp
index 8786039..366292a 100644
--- a/lib/engine/components/resource-list/rl-heap.cpp
+++ b/lib/engine/components/resource-list/rl-heap.cpp
@@ -46,12 +46,13 @@
 #include "rl-heap.h"
 
 RL::Heap::Heap (Ekiga::ServiceCore& services_,
+		std::tr1::shared_ptr<xmlDoc> doc_,
 		xmlNodePtr node_):
   services(services_),
   node(node_), name(NULL),
   root(NULL), user(NULL),
   username(NULL), password(NULL),
-  doc(NULL), list_node(NULL)
+  doc(doc_), list_node(NULL)
 {
   {
     xmlChar* xml_str = NULL;
@@ -99,7 +100,7 @@ RL::Heap::Heap (Ekiga::ServiceCore& services_,
 
   if (name == NULL)
     name = xmlNewChild (node, NULL, BAD_CAST "name",
-			BAD_CAST robust_xmlEscape(node->doc,
+			BAD_CAST robust_xmlEscape(doc.get (),
 						  _("Unnamed")).c_str ());
   if (root == NULL)
     root = xmlNewChild (node, NULL, BAD_CAST "root", BAD_CAST "");
@@ -114,6 +115,7 @@ RL::Heap::Heap (Ekiga::ServiceCore& services_,
 }
 
 RL::Heap::Heap (Ekiga::ServiceCore& services_,
+		std::tr1::shared_ptr<xmlDoc> doc_,
 		const std::string name_,
 		const std::string root_,
 		const std::string user_,
@@ -124,7 +126,7 @@ RL::Heap::Heap (Ekiga::ServiceCore& services_,
   node(NULL), name(NULL),
   root(NULL), user(NULL),
   username(NULL), password(NULL),
-  doc(NULL), list_node(NULL)
+  doc(doc_), list_node(NULL)
 {
   node = xmlNewNode (NULL, BAD_CAST "entry");
   if (writable_)
@@ -163,8 +165,6 @@ RL::Heap::Heap (Ekiga::ServiceCore& services_,
 
 RL::Heap::~Heap ()
 {
-  if (doc != NULL)
-    xmlFreeDoc (doc);
 }
 
 const std::string
@@ -264,9 +264,7 @@ RL::Heap::refresh ()
     presentities.erase (presentities.begin()->first);
   }
 
-  if (doc)
-    xmlFreeDoc (doc);
-  doc = NULL;
+  doc.reset ();
 
   xcap->read (path, sigc::mem_fun (this, &RL::Heap::on_document_received));
 }
@@ -288,9 +286,10 @@ RL::Heap::on_document_received (bool error,
 void
 RL::Heap::parse_doc (std::string raw)
 {
-  doc = xmlRecoverMemory (raw.c_str (), raw.length ());
-
-  xmlNodePtr doc_root = xmlDocGetRootElement (doc);
+  doc = std::tr1::shared_ptr<xmlDoc> (xmlRecoverMemory (raw.c_str (), raw.length ()), xmlFreeDoc);
+  if ( !doc)
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+  xmlNodePtr doc_root = xmlDocGetRootElement (doc.get ());
 
   if (doc_root == NULL
       || doc_root->name == NULL
@@ -298,8 +297,7 @@ RL::Heap::parse_doc (std::string raw)
 
     std::cout << "Invalid document in " << __PRETTY_FUNCTION__ << std::endl;
     // FIXME: warn the user somehow?
-    xmlFreeDoc (doc);
-    doc = NULL;
+    doc.reset ();
   } else {
 
 
@@ -369,7 +367,7 @@ RL::Heap::parse_list (xmlNodePtr list)
 	&& child->name != NULL
 	&& xmlStrEqual (BAD_CAST ("entry"), child->name)) {
 
-      gmref_ptr<Presentity> presentity(new Presentity (services, path, child, writable));
+      gmref_ptr<Presentity> presentity(new Presentity (services, path, doc, child, writable));
       std::list<sigc::connection> conns;
       conns.push_back (presentity->updated.connect (sigc::bind (presentity_updated.make_slot (),presentity)));
       conns.push_back (presentity->removed.connect (sigc::bind(presentity_removed.make_slot (),presentity)));
@@ -571,10 +569,10 @@ RL::Heap::on_new_entry_form_submitted (bool submitted,
     xmlNodePtr entry_node = xmlNewChild (list_node, NULL,
 					 BAD_CAST "entry", NULL);
     xmlSetProp (entry_node, BAD_CAST "uri",
-		BAD_CAST robust_xmlEscape (doc, entry_uri).c_str ());
+		BAD_CAST robust_xmlEscape (doc.get (), entry_uri).c_str ());
     xmlNewChild (entry_node, NULL, BAD_CAST "display-name",
-		 BAD_CAST robust_xmlEscape (doc, entry_name).c_str ());
-    xmlNsPtr ns = xmlSearchNsByHref (doc, entry_node,
+		 BAD_CAST robust_xmlEscape (doc.get (), entry_name).c_str ());
+    xmlNsPtr ns = xmlSearchNsByHref (doc.get (), entry_node,
 				     BAD_CAST "http://www.ekiga.org";);
     if (ns == NULL) {
 
@@ -586,11 +584,11 @@ RL::Heap::on_new_entry_form_submitted (bool submitted,
 	 ++iter) {
 
       xmlNewChild (entry_node, ns, BAD_CAST "group",
-		   BAD_CAST robust_xmlEscape (doc, *iter).c_str ());
+		   BAD_CAST robust_xmlEscape (doc.get (), *iter).c_str ());
     }
 
     xmlBufferPtr buffer = xmlBufferCreate ();
-    int res = xmlNodeDump (buffer, doc, entry_node, 0, 0);
+    int res = xmlNodeDump (buffer, doc.get (), entry_node, 0, 0);
 
     if (res >= 0) {
 
diff --git a/lib/engine/components/resource-list/rl-heap.h b/lib/engine/components/resource-list/rl-heap.h
index e457622..02fc370 100644
--- a/lib/engine/components/resource-list/rl-heap.h
+++ b/lib/engine/components/resource-list/rl-heap.h
@@ -49,6 +49,7 @@ namespace RL {
   public:
 
     Heap (Ekiga::ServiceCore& services_,
+	  std::tr1::shared_ptr<xmlDoc> doc_,
 	  xmlNodePtr node);
 
     /* name: the name of the Heap in the GUI
@@ -62,6 +63,7 @@ namespace RL {
      *
      */
     Heap (Ekiga::ServiceCore& core_,
+	  std::tr1::shared_ptr<xmlDoc> doc_,
 	  const std::string name_,
 	  const std::string root_,
 	  const std::string user_,
@@ -101,7 +103,7 @@ namespace RL {
     xmlNodePtr username;
     xmlNodePtr password;
 
-    xmlDocPtr doc;
+    std::tr1::shared_ptr<xmlDoc> doc;
     xmlNodePtr list_node;
 
     std::map<gmref_ptr<Presentity>, std::list<sigc::connection> > presentities;
diff --git a/lib/engine/components/resource-list/rl-list.cpp b/lib/engine/components/resource-list/rl-list.cpp
index 974641e..359e9af 100644
--- a/lib/engine/components/resource-list/rl-list.cpp
+++ b/lib/engine/components/resource-list/rl-list.cpp
@@ -82,7 +82,7 @@ public: // no need to make anything private
 
   std::string group;
 
-  xmlDocPtr doc;
+  std::tr1::shared_ptr<xmlDoc> doc;
   xmlNodePtr node;
 
   xmlNodePtr name_node;
@@ -172,7 +172,7 @@ RL::ListImpl::ListImpl (Ekiga::ServiceCore& core_,
 			int pos,
 			const std::string group_,
 			xmlNodePtr node_):
-  core(core_), position(pos), group(group_), doc(NULL), node(node_)
+  core(core_), position(pos), group(group_), doc(), node(node_)
 {
   {
     gchar* raw = NULL;
@@ -214,8 +214,6 @@ RL::ListImpl::ListImpl (Ekiga::ServiceCore& core_,
 
 RL::ListImpl::~ListImpl ()
 {
-  if (doc != NULL)
-    xmlFreeDoc (doc);
 }
 
 bool
@@ -248,9 +246,7 @@ RL::ListImpl::flush ()
   }
   entries.clear ();
 
-  if (doc != NULL)
-    xmlFreeDoc (doc);
-  doc = NULL;
+  doc.reset ();
   node = NULL;
   name_node = NULL;
 }
@@ -274,8 +270,10 @@ RL::ListImpl::on_xcap_answer (bool error,
 
   } else {
 
-    doc = xmlRecoverMemory (value.c_str (), value.length ());
-    node = xmlDocGetRootElement (doc);
+    doc = std::tr1::shared_ptr<xmlDoc> (xmlRecoverMemory (value.c_str (), value.length ()), xmlFreeDoc);
+    if ( !doc)
+      doc = std::tr1::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
+    node = xmlDocGetRootElement (doc.get ());
     if (node == NULL
 	|| node->name == NULL
 	|| !xmlStrEqual (BAD_CAST "list", node->name)) {
@@ -341,7 +339,7 @@ RL::ListImpl::parse ()
       gmref_ptr<Entry> entry = gmref_ptr<Entry> (new Entry (core, path,
 							    entry_pos,
 							    display_name,
-							    child));
+							    doc, child));
       std::list<sigc::connection> conns;
       conns.push_back (entry->updated.connect (sigc::bind (entry_updated.make_slot (), entry)));
       conns.push_back (entry->removed.connect (sigc::bind (entry_removed.make_slot (), entry)));
diff --git a/lib/engine/components/resource-list/rl-presentity.cpp b/lib/engine/components/resource-list/rl-presentity.cpp
index 8011504..46f4255 100644
--- a/lib/engine/components/resource-list/rl-presentity.cpp
+++ b/lib/engine/components/resource-list/rl-presentity.cpp
@@ -48,14 +48,15 @@
 
 RL::Presentity::Presentity (Ekiga::ServiceCore &services_,
 			    gmref_ptr<XCAP::Path> path_,
+			    std::tr1::shared_ptr<xmlDoc> doc_,
 			    xmlNodePtr node_,
 			    bool writable_) :
-  services(services_), node(node_), writable(writable_), name_node(NULL),
-  presence("unknown"), status(""), avatar("")
+  services(services_), doc(doc_), node(node_), writable(writable_),
+  name_node(NULL), presence("unknown"), status(""), avatar("")
 {
   gmref_ptr<Ekiga::PresenceCore> presence_core(services.get ("presence-core"));
   xmlChar *xml_str = NULL;
-  xmlNsPtr ns = xmlSearchNsByHref (node->doc, node,
+  xmlNsPtr ns = xmlSearchNsByHref (doc.get (), node,
 				   BAD_CAST "http://www.ekiga.org";);
 
   if (ns == NULL) {
diff --git a/lib/engine/components/resource-list/rl-presentity.h b/lib/engine/components/resource-list/rl-presentity.h
index b7ca882..5719621 100644
--- a/lib/engine/components/resource-list/rl-presentity.h
+++ b/lib/engine/components/resource-list/rl-presentity.h
@@ -39,6 +39,7 @@
 #define __RL_PRESENTITY_H__
 
 #include <libxml/tree.h>
+#include <tr1/memory>
 
 #include "form.h"
 #include "presence-core.h"
@@ -55,6 +56,7 @@ namespace RL
 
     Presentity (Ekiga::ServiceCore &_core,
 		gmref_ptr<XCAP::Path> path_,
+		std::tr1::shared_ptr<xmlDoc> doc_,
 		xmlNodePtr _node,
 		bool writable_);
 
@@ -99,6 +101,7 @@ namespace RL
     Ekiga::ServiceCore &services;
 
     gmref_ptr<XCAP::Path> path;
+    std::tr1::shared_ptr<xmlDoc> doc;
     xmlNodePtr node;
     bool writable;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]