? sites/default/files
? sites/default/settings.php
? sites/default/themes
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.250
diff -u -p -r1.250 filter.module
--- modules/filter/filter.module	14 May 2009 08:23:14 -0000	1.250
+++ modules/filter/filter.module	17 May 2009 01:08:52 -0000
@@ -750,14 +750,14 @@ function _filter_htmlcorrector($text) {
     $no_nesting = drupal_map_assoc(array('li', 'p'));
 
     // Single use tags in HTML4
-    $single_use = drupal_map_assoc(array('base', 'meta', 'link', 'hr', 'br', 'param', 'img', 'area', 'input', 'col', 'frame'));
+    $single_use = drupal_map_assoc(array('base', 'meta', 'link', 'hr', 'br', 'param', 'img', 'area', 'input', 'col', 'frame', '!--'));
   }
 
   // Properly entify angles.
-  $text = preg_replace('!<([^a-zA-Z/])!', '&lt;\1', $text);
+  $text = preg_replace('@<([^a-zA-Z/!])@', '&lt;\1', $text);
 
   // Split tags from text.
-  $split = preg_split('/<([^>]+?)>/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+  $split = preg_split('/<(!--.*?--|[^>]+?)>/s', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
   // Note: PHP ensures the array consists of alternating delimiters and literals
   // and begins and ends with a literal (inserting $null as required).
 
@@ -767,7 +767,7 @@ function _filter_htmlcorrector($text) {
   foreach ($split as $value) {
     // Process HTML tags.
     if ($tag) {
-      list($tagname) = explode(' ', strtolower($value), 2);
+      list($tagname) = preg_split('/\s/', strtolower($value), 2);
       // Closing tag
       if ($tagname{0} == '/') {
         $tagname = substr($tagname, 1);
@@ -794,7 +794,7 @@ function _filter_htmlcorrector($text) {
           array_unshift($stack, $tagname);
         }
         // Add trailing slash to single-use tags as per X(HT)ML.
-        else {
+        elseif ($tagname !== '!--') {
           $value = rtrim($value, ' /') . ' /';
         }
         $output .= '<' . $value . '>';
@@ -862,7 +862,7 @@ function _filter_autop($text) {
   // We don't apply any processing to the contents of these tags to avoid messing
   // up code. We look for matched pairs and allow basic nesting. For example:
   // "processed <pre> ignored <script> ignored </script> ignored </pre> processed"
-  $chunks = preg_split('@(</?(?:pre|script|style|object)[^>]*>)@i', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+  $chunks = preg_split('@(<(?:!--.*?--|/?(?:pre|script|style|object)[^>]*)>)@si', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
   // Note: PHP ensures the array consists of alternating delimiters and literals
   // and begins and ends with a literal (inserting NULL as required).
   $ignore = FALSE;
Index: modules/filter/filter.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.test,v
retrieving revision 1.19
diff -u -p -r1.19 filter.test
--- modules/filter/filter.test	25 Apr 2009 18:01:10 -0000	1.19
+++ modules/filter/filter.test	17 May 2009 01:08:52 -0000
@@ -233,4 +233,15 @@ class FilterTestCase extends DrupalWebTe
       $this->drupalPost('admin/settings/filter/delete/' . $format->format, array(), t('Delete'));
     }
   }
+
+  /**
+   * Test that the HTML corrector doesn't change the contents of HTML comments.
+   */
+  function testHtmlCorrectorComments() {
+    $f = _filter_autop("<!-- aaa\nbbb\n\nccc -->");
+    $this->assertEqual($f, "<!-- aaa\nbbb\n\nccc -->", t('Line breaking -- do not change comments.'));
+
+    $f = _filter_htmlcorrector("<!--\n<p> <br> comment\n//-->");
+    $this->assertEqual($f, "<!--\n<p> <br> comment\n//-->", t('HTML corrector -- skipping comments.'));
+  }
 }
