[libxml++] SaxParser: Start each parsing with a new Document for entity resolution



commit f24a21cd7f19feb79a2145fb3973e4cd4d69f322
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Wed Sep 23 17:08:19 2015 +0200

    SaxParser: Start each parsing with a new Document for entity resolution
    
    * libxml++/parsers/saxparser.[h|cc]: Make entity_resolver_doc_ a unique_ptr.
    Create a new Document in an overridden initialize_context(). Bug #754673.

 libxml++/parsers/saxparser.cc |   33 ++++++++++++++++-----------------
 libxml++/parsers/saxparser.h  |    3 ++-
 2 files changed, 18 insertions(+), 18 deletions(-)
---
diff --git a/libxml++/parsers/saxparser.cc b/libxml++/parsers/saxparser.cc
index 69ebae0..20fc5d8 100644
--- a/libxml++/parsers/saxparser.cc
+++ b/libxml++/parsers/saxparser.cc
@@ -39,7 +39,7 @@ struct SaxParserCallback
 
 
 SaxParser::SaxParser(bool use_get_entity)
-  : sax_handler_( new _xmlSAXHandler )
+  : sax_handler_(new _xmlSAXHandler), entity_resolver_doc_(new Document)
 {
   xmlSAXHandler temp = {
     SaxParserCallback::internal_subset,
@@ -88,12 +88,12 @@ SaxParser::~SaxParser()
 
 xmlEntityPtr SaxParser::on_get_entity(const Glib::ustring& name)
 {
-  return entity_resolver_doc_.get_entity(name);
+  return entity_resolver_doc_->get_entity(name);
 }
 
 void SaxParser::on_entity_declaration(const Glib::ustring& name, XmlEntityType type, const Glib::ustring& 
publicId, const Glib::ustring& systemId, const Glib::ustring& content)
 {
-  entity_resolver_doc_.set_entity_declaration(name, type, publicId, systemId, content);
+  entity_resolver_doc_->set_entity_declaration(name, type, publicId, systemId, content);
 }  
 
 void SaxParser::on_start_document()
@@ -142,21 +142,13 @@ void SaxParser::on_internal_subset(const Glib::ustring& name,
                          const Glib::ustring& publicId,
                          const Glib::ustring& systemId)
 {
-  entity_resolver_doc_.set_internal_subset(name, publicId, systemId);
+  entity_resolver_doc_->set_internal_subset(name, publicId, systemId);
 }
 
 // implementation of this function is inspired by the SAX documentation by James Henstridge.
 // (http://www.daa.com.au/~james/gnome/xml-sax/implementing.html)
 void SaxParser::parse()
 {
-  //TODO If this is not the first parsing with this SaxParser, the xmlDoc object
-  // in entity_resolver_doc_ should be deleted and replaced by a new one.
-  // Otherwise entity declarations from a previous parsing may erroneously affect
-  // this parsing. This would be much easier if entity_resolver_doc_ were a
-  // std::unique_ptr<Document>, so the xmlpp::Document could be deleted and a new
-  // one created. A good place for such code would be in an overridden
-  // SaxParser::initialize_context(). It would be an ABI break.
-
   if(!context_)
   {
     throw internal_error("Parser context not created.");
@@ -326,11 +318,6 @@ void SaxParser::parse_chunk_raw(const unsigned char* contents, size_type bytes_c
   }
 }
 
-void SaxParser::release_underlying()
-{
-  Parser::release_underlying();
-}
-
 void SaxParser::finish_chunk_parsing()
 {
   xmlResetLastError();
@@ -371,6 +358,18 @@ void SaxParser::finish_chunk_parsing()
   }
 }
 
+void SaxParser::release_underlying()
+{
+  Parser::release_underlying();
+}
+
+void SaxParser::initialize_context()
+{
+  Parser::initialize_context();
+  // Start with an empty Document for entity resolution.
+  entity_resolver_doc_.reset(new Document);
+}
+
 
 xmlEntityPtr SaxParserCallback::get_entity(void* context, const xmlChar* name)
 {
diff --git a/libxml++/parsers/saxparser.h b/libxml++/parsers/saxparser.h
index 60a18aa..90e845d 100644
--- a/libxml++/parsers/saxparser.h
+++ b/libxml++/parsers/saxparser.h
@@ -209,6 +209,7 @@ protected:
   virtual void on_entity_declaration(const Glib::ustring& name, XmlEntityType type, const Glib::ustring& 
publicId, const Glib::ustring& systemId, const Glib::ustring& content);
 
   void release_underlying() override;
+  void initialize_context() override;
   
 private:
   void parse();
@@ -217,7 +218,7 @@ private:
 
   // A separate xmlpp::Document that is just used for entity resolution,
   // and never seen in the API:
-  xmlpp::Document entity_resolver_doc_;
+  std::unique_ptr<Document> entity_resolver_doc_;
 
   friend struct SaxParserCallback;
 };


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