From a962b3e8e67fb4b1cd913f40ff1b72f9144e3600 Mon Sep 17 00:00:00 2001
From: Peter Philipp <peter.philipp@cando-image.com>
Date: Tue, 8 Nov 2011 21:37:58 +0100
Subject: [PATCH] Issue #998590 by Charles51, das-peter, pisco: Prevent double
 CDATA section escaping in
 filter_dom_serialize_escape_cdata_element() to avoid
 warnings

---
 core/modules/filter/filter.module |    9 ++++-
 core/modules/filter/filter.test   |   73 +++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 1 deletions(-)

diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 2ad725a..e857224 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -1107,8 +1107,15 @@ function filter_dom_serialize_escape_cdata_element($dom_document, $dom_element,
       // See drupal_get_js().  This code is more or less duplicated there.
       $embed_prefix = "\n<!--{$comment_start}--><![CDATA[{$comment_start} ><!--{$comment_end}\n";
       $embed_suffix = "\n{$comment_start}--><!]]>{$comment_end}\n";
+
+      // Prevent invalid cdata escaping as this would throw a DOM error.
+      // This is the same behaviour as found in libxml2.
+      // Related W3C standard: http://www.w3.org/TR/REC-xml/#dt-cdsection
+      // Fix explanation: http://en.wikipedia.org/wiki/CDATA#Nesting
+      $data = str_replace(']]>', ']]]]><![CDATA[>', $node->data);
+
       $fragment = $dom_document->createDocumentFragment();
-      $fragment->appendXML($embed_prefix . $node->data . $embed_suffix);
+      $fragment->appendXML($embed_prefix . $data . $embed_suffix);
       $dom_element->appendChild($fragment);
       $dom_element->removeChild($node);
     }
diff --git a/core/modules/filter/filter.test b/core/modules/filter/filter.test
index 67d0833..2bafd47 100644
--- a/core/modules/filter/filter.test
+++ b/core/modules/filter/filter.test
@@ -1637,6 +1637,79 @@ alert("test")
  /* Styling */ body {color:red}
 /*--><!]]>*/
 </style></p>', t('HTML corrector -- CDATA added to a style element.'));
+
+    $filtered_data = _filter_htmlcorrector('<p><style>
+/*<![CDATA[*/
+/* Styling */
+body {color:red}
+/*]]>*/
+</style></p>');
+    $this->assertEqual($filtered_data, '<p><style>
+<!--/*--><![CDATA[/* ><!--*/
+
+/*<![CDATA[*/
+/* Styling */
+body {color:red}
+/*]]]]><![CDATA[>*/
+
+/*--><!]]>*/
+</style></p>',
+      t('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '/*<![CDATA[*/'))
+    );
+
+    $filtered_data = _filter_htmlcorrector('<p><style>
+  <!--/*--><![CDATA[/* ><!--*/
+  /* Styling */
+  body {color:red}
+  /*--><!]]>*/
+</style></p>');
+    $this->assertEqual($filtered_data, '<p><style>
+<!--/*--><![CDATA[/* ><!--*/
+
+  <!--/*--><![CDATA[/* ><!--*/
+  /* Styling */
+  body {color:red}
+  /*--><!]]]]><![CDATA[>*/
+
+/*--><!]]>*/
+</style></p>',
+      t('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '<!--/*--><![CDATA[/* ><!--*/'))
+    );
+
+    $filtered_data = _filter_htmlcorrector('<p><script type="text/javascript">
+<!--//--><![CDATA[// ><!--
+  alert("test");
+//--><!]]>
+</script></p>');
+    $this->assertEqual($filtered_data, '<p><script type="text/javascript">
+<!--//--><![CDATA[// ><!--
+
+<!--//--><![CDATA[// ><!--
+  alert("test");
+//--><!]]]]><![CDATA[>
+
+//--><!]]>
+</script></p>',
+      t('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '<!--//--><![CDATA[// ><!--'))
+    );
+
+    $filtered_data = _filter_htmlcorrector('<p><script type="text/javascript">
+// <![CDATA[
+  alert("test");
+// ]]>
+</script></p>');
+    $this->assertEqual($filtered_data, '<p><script type="text/javascript">
+<!--//--><![CDATA[// ><!--
+
+// <![CDATA[
+  alert("test");
+// ]]]]><![CDATA[>
+
+//--><!]]>
+</script></p>',
+      t('HTML corrector -- Existing cdata section @pattern_name properly escaped', array('@pattern_name' => '// <![CDATA['))
+    );
+
   }
 
   /**
-- 
1.7.7.msysgit.1

