[glom] Do not create XML documents containing form feeds.



commit 6a2969d6b9da1b0c03b5c8e0037a2e874aa71a0d
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Sep 9 17:09:01 2011 +0200

    Do not create XML documents containing form feeds.
    
    * glom/libglom/utils.[h|cc]: Added string_clean_for_xml(), though it is
    currently inefficient and copies the whole string even when not changing it.
    * glom/libglom/document/document.cc: set_child_text_node(),
    set_node_text_child_as_value(), save_before(): Always use that utility
    method before giving the child text string to libxml, because libxml will
    just write it out to the file, creating an invalid XML file that it can't
    read back in.

 ChangeLog                         |   12 ++++++++++++
 glom/libglom/document/document.cc |   18 +++++++++++-------
 glom/libglom/utils.cc             |    9 +++++++++
 glom/libglom/utils.h              |    4 ++++
 4 files changed, 36 insertions(+), 7 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 98419c0..f24d56f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2011-09-09  Murray Cumming  <murrayc murrayc com>
 
+	Do not create XML documents containing form feeds.
+
+	* glom/libglom/utils.[h|cc]: Added string_clean_for_xml(), though it is 
+	currently inefficient and copies the whole string even when not changing it.
+	* glom/libglom/document/document.cc: set_child_text_node(), 
+	set_node_text_child_as_value(), save_before(): Always use that utility 
+	method before giving the child text string to libxml, because libxml will 
+	just write it out to the file, creating an invalid XML file that it can't
+	read back in.
+
+2011-09-09  Murray Cumming  <murrayc murrayc com>
+
 	Related records portals: Allow navigation via read-only relationships.
 
 	* glom/mode_data/box_data_list_related.cc: on_adddel_user_requested_edit():
diff --git a/glom/libglom/document/document.cc b/glom/libglom/document/document.cc
index 45571f8..8984984 100644
--- a/glom/libglom/document/document.cc
+++ b/glom/libglom/document/document.cc
@@ -1131,11 +1131,13 @@ void Document::set_child_text_node(xmlpp::Element* node, const Glib::ustring& ch
     child = node->add_child(child_node_name);
   }
 
+  const Glib::ustring text_used = Utils::string_clean_for_xml(text);
+
   xmlpp::TextNode* text_child = child->get_child_text();
   if(!text_child)
-    child->add_child_text(text);
+    child->add_child_text(text_used);
   else
-    text_child->set_content(text);
+    text_child->set_content(text_used);
 }
 
 void Document::set_node_attribute_value_as_bool(xmlpp::Element* node, const Glib::ustring& strAttributeName, bool value, bool value_default)
@@ -1249,9 +1251,11 @@ void Document::set_node_attribute_value_as_value(xmlpp::Element* node, const Gli
 
 void Document::set_node_text_child_as_value(xmlpp::Element* node, const Gnome::Gda::Value& value, Field::glom_field_type field_type)
 {
+  if(!node)
+    return;
+
   const Glib::ustring value_as_text = Field::to_file_format(value, field_type);
-  if(node)
-    node->set_child_text(value_as_text);
+  node->set_child_text( Utils::string_clean_for_xml(value_as_text) );
 }
 
 Gnome::Gda::Value Document::get_node_attribute_value_as_value(const xmlpp::Element* node, const Glib::ustring& strAttributeName, Field::glom_field_type field_type)
@@ -3812,7 +3816,7 @@ bool Document::save_before()
           if(!page_setup.empty())
           {
             xmlpp::Element* child = nodePrintLayout->add_child(GLOM_NODE_PAGE_SETUP);
-            child->add_child_text(page_setup);
+            child->add_child_text( Utils::string_clean_for_xml(page_setup) );
           }
 
           xmlpp::Element* nodeGroups = nodePrintLayout->add_child(GLOM_NODE_DATA_LAYOUT_GROUPS);
@@ -3891,9 +3895,9 @@ bool Document::save_before()
       //The script is in a child text node:
       xmlpp::TextNode* text_child = nodeModule->get_child_text();
       if(!text_child)
-        nodeModule->add_child_text(script);
+        nodeModule->add_child_text( Utils::string_clean_for_xml(script) );
       else
-       text_child->set_content(script);
+       text_child->set_content( Utils::string_clean_for_xml(script) );
     }
   }
 
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 52a37c1..78dae7c 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -194,6 +194,15 @@ Glib::ustring Utils::string_replace(const Glib::ustring& src, const Glib::ustrin
 */
 }
 
+Glib::ustring Utils::string_clean_for_xml(const Glib::ustring& src)
+{
+  // The form feed character may not be in XML, even if escaped.
+  // So lets just lose it.
+  // Other unusual characters, such as &, are escaped by libxml later.
+  // TODO_Performance: Find a quicker way to do this.
+  return string_replace(src, "\f", Glib::ustring());
+}
+
 
 Glib::RefPtr<Gnome::Gda::SqlBuilder> Utils::build_sql_select_with_where_clause(const Glib::ustring& table_name, const type_vecLayoutFields& fieldsToGet, const Gnome::Gda::SqlExpr& where_clause, const sharedptr<const Relationship>& extra_join, const type_sort_clause& sort_clause, guint limit)
 {
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index 4efd0b0..09a8826 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -44,6 +44,10 @@ Glib::ustring trim_whitespace(const Glib::ustring& text);
 
 Glib::ustring string_replace(const Glib::ustring& src, const Glib::ustring& search_for, const Glib::ustring& replace_with);
 
+/** Remove any characters that may not be in XML even when escaped.
+ */
+Glib::ustring string_clean_for_xml(const Glib::ustring& src);
+
 //typedef Base_DB::type_vecLayoutFields type_vecLayoutFields;
 typedef std::vector< sharedptr<LayoutItem_Field> > type_vecLayoutFields;
 typedef std::vector< sharedptr<const LayoutItem_Field> > type_vecConstLayoutFields;



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