Index: modules/filter/filter.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.test,v
retrieving revision 1.8
diff -u -p -r1.8 filter.test
--- modules/filter/filter.test	12 Oct 2008 04:30:06 -0000	1.8
+++ modules/filter/filter.test	20 Nov 2008 21:43:12 -0000
@@ -216,7 +216,53 @@ class FilterTestCase extends DrupalWebTe
    * Test the HTML filter
    */
   function testHtmlFilter() {
+    foreach ($this->getTestFilterHtml() as $id => $html) {
+      // Disable nofollow option.
+      variable_set('filter_html_nofollow_1', FALSE);
+      // Set allowed tags.
+      variable_set('allowed_html_1', $html['tags']);
+      // Filter tags out.
+      $filtered = _filter_html($html['original'], 1);
+      $this->assertEqual($filtered, $html['expected'], t('_filter_html() properly allows %tags: %scenario', array('%tags' => $html['tags'], '%scenario' => $html['scenario'])));
+      if (isset($html['expected_nofollow'])) {
+        // Enable nofollow option.
+        variable_set('filter_html_nofollow_1', TRUE);
+        // Filter and add rel=nofollow attribute.
+        $filtered = _filter_html($html['original'], 1);
+        $this->assertEqual($filtered, $html['expected_nofollow'], t('_filter_html() properly allows %tags and adds rel=nofollow when filter_html_nofollow is enabled: %scenario', array('%tags' => $html['tags'], '%scenario' => $html['scenario'])));
+      }
+      if (isset($html['expected_nohtml'])) {
+        // Escape all HTML. 
+        $filtered = trim(check_plain($html['original']));
+        $this->assertEqual($filtered, $html['expected_nohtml'], t('All html tags properly removed: %scenario', array('%scenario' => $html['scenario'])));
+      }
+    }
+  }
 
+  /**
+   * Test the HTML corrector.
+   */
+  function testHtmlCorrector() {
+    foreach ($this->_getTestHtml() as $id => $html) {
+      $filtered = _filter_htmlcorrector($html['original']);
+      $this->assertEqual($filtered, $html['expected'], t('filter_htmlcorrector() properly fixes broken HTML: %scenario', array('%scenario' => $html['scenario'])));
+    }
+  }
+
+  /**
+   * Test URL filter.
+   */
+  function testUrlFilter() {
+    $url_long = 'http://www.example.com/sample/foo.html?variable=value&variable2=value2#anchor1';
+    // Test url length filter.
+    $trimmed = _filter_url_trim($url_long, 27);
+    $this->assertEqual($trimmed, 'http://www.example.com/samp...', t('_filter_url_trim() function properly trims a long url.'));
+
+    // Test www domains.
+    foreach ($this->_getTestUrls() as $id => $url) {
+      $filtered = _filter_url($url['original'], 1);
+      $this->assertEqual($filtered, $url['expected'], t('URL filter properly converts: @scenario', array('@scenario' => $url['scenario'])));
+    }
   }
 
   function createFormat($filter) {
@@ -235,4 +281,150 @@ class FilterTestCase extends DrupalWebTe
       $this->drupalPost('admin/settings/filters/delete/' . $format->format, array(), t('Delete'));
     }
   }
+
+  /**
+   * Get text with urls to test.
+   *
+   * @return
+   *   Array of associative arrays containing:
+   *     - scenario
+   *     - original
+   *     - expected
+   */
+  function _getTestUrls() {
+    return array(
+      array(
+        'scenario' => t('domain beginning with www in the middle of a sentence.'),
+        'original' => 'A bit of text with a simple www domain placed in the middle www.example.com/foo/bar, like so.',
+        'expected' => 'A bit of text with a simple www domain placed in the middle <a href="http://www.example.com/foo/bar" title="www.example.com/foo/bar">www.example.com/foo/bar</a>, like so.',
+      ),
+      array(
+        'scenario' => t('list item beggining with a domain.'),
+        'original' => '<p>A list</p><ul class="menu"><li>with</li><li>a domain beginning on a list item:</li><li>www.sample.com</li></ul><p>as so.</p>',
+        'expected' => '<p>A list</p><ul class="menu"><li>with</li><li>a domain beginning on a list item:</li><li><a href="http://www.sample.com" title="www.sample.com">www.sample.com</a></li></ul><p>as so.</p>',
+      ),
+      array(
+        'scenario' => t('email address'),
+        'original' => 'An email address, positioned foobar@example.com in the middle of a sentence.',
+        'expected' => 'An email address, positioned <a href="mailto:foobar@example.com">foobar@example.com</a> in the middle of a sentence.',
+      ),
+      array(
+        'scenario' => t('Insanely long links'),
+        'original' => 'A http://www.reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyloong.com/link/to/test/on/the/url/filtere/index.html?but=wait&theres=more#also_an_anchor domain to test.',
+        'expected' => 'A <a href="http://www.reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyloong.com/link/to/test/on/the/url/filtere/index.html?but=wait&amp;theres=more#also_an_anchor" title="http://www.reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyloong.com/link/to/test/on/the/url/filtere/index.html?but=wait&amp;theres=more#also_an_anchor">http://www.reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyr...</a> domain to test.',
+      ),
+      // These should go unchanged
+      array(
+        'scenario' => t('does not replace urls in anchor tags'),
+        'original' => 'An anchor tag in <a href="http://example.com" title="foo">http://example.com</a> the middle of a sentence.',
+        'expected' => 'An anchor tag in <a href="http://example.com" title="foo">http://example.com</a> the middle of a sentence.',
+      ),
+    );
+  }
+
+  /**
+   * Get text with to test _filter_htmlcorrector().
+   *
+   * @return
+   *   Array of associative arrays containing:
+   *     - scenario
+   *     - original
+   *     - expected
+   */
+  function _getTestHtml() {
+    return array(
+      array(
+        // Note: This first scenario will fail. This is intentional so the
+        // comment (#222926) issue can be fixed.
+        'scenario' => t('HTML comments are preserved.'),
+        'original' => '<p>
+Foobar foobar
+<!-- Here, a comment describing something or other, with some broken <p>html inside of it. 
+     In theory, this should not be escaped, but in practice, it breaks. -->
+</p>',
+        'expected' => '<p>
+Foobar foobar
+<!-- Here, a comment describing something or other, with some broken <p>html inside of it. 
+     In theory, this should not be escaped, but in practice, it breaks. -->
+</p>',
+      ),
+      array(
+        // This test will also fail. See above test.
+        'scenario' => t('Incomplete comment is fixed.'),
+        'original' => 'A comment gets started <!-- A comment, that is <strong>not</strong> closed.
+Should the corrector close it at the first line? <em>Or</em> will it comment out the <i>rest of the node</i>?',
+        'expected' => 'st',
+      ),
+      array(
+        'scenario' => t('Missing closing p, li and ul tags.'),
+        'original' => '<p>Here are some examples <img src="foo/bar.gif" /> some missing tags:
+<ul>
+  <li>One, this unordered list will not be properly closed.
+  <li>Two, the above list item is also not closed.
+We\'ll certainly see what happens.',
+        'expected' => '<p>Here are some examples <img src="foo/bar.gif" /> some missing tags:
+<ul>
+  <li>One, this unordered list will not be properly closed.
+  </li><li>Two, the above list item is also not closed.
+We\'ll certainly see what happens.</li></ul></p>',
+      ),
+      array(
+        'scenario' => t('Changes <br> tags to <br />'),
+        'original' => '<p align="right">
+Look a <strong>paragraph<br></strong>!
+</p><br>
+<br>
+',
+        'expected' => '<p align="right">
+Look a <strong>paragraph<br /></strong>!
+</p><br />
+<br />
+',
+      ),
+    );
+  }
+
+  /**
+   * HTML to test _filter_html() function.
+   *
+   * @return
+   *   Array of associative arrays containing:
+   *     - original
+   *     - expected
+   *     - expected_nofollow
+   *     - expected_nohtml
+   *     - tags
+   */
+  function getTestFilterHtml() {
+    $htmls = array(
+      array(
+        'scenario' => t('Tags and simple XSS'),
+        'tags' => '<p> <ul> <ol> <li> <strong> <img> <a>',
+        'original' => '<div onlick="hackMe();">That div tag should hopefully be stripped out, but also, an allowed tag, such as <strong onclick="hackMeAgain();">strong</strong> should be properly sanitized.
+
+Also, any <a href="http://example.com">links should have the nofollow attribute added when that option is enabled.
+',
+        'expected' => 'That div tag should hopefully be stripped out, but also, an allowed tag, such as <strong>strong</strong> should be properly sanitized.
+
+Also, any <a href="http://example.com">links should have the nofollow attribute added when that option is enabled.',
+        'expected_nofollow' => 'That div tag should hopefully be stripped out, but also, an allowed tag, such as <strong>strong</strong> should be properly sanitized.
+
+Also, any <a href="http://example.com" rel="nofollow">links should have the nofollow attribute added when that option is enabled.',
+        'expected_nohtml' => '&lt;div onlick=&quot;hackMe();&quot;&gt;That div tag should hopefully be stripped out, but also, an allowed tag, such as &lt;strong onclick=&quot;hackMeAgain();&quot;&gt;strong&lt;/strong&gt; should be properly sanitized.
+
+Also, any &lt;a href=&quot;http://example.com&quot;&gt;links should have the nofollow attribute added when that option is enabled.',
+      ),
+      //The XSS samples below courtesy of http://ha.ckers.org/xss.html
+      array(
+        'scenario' => t('Complex XSS: %xss', array('%xss' => '<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>')),
+        'tags' => '<img>',
+        'original' => '<p>A hacked image tag: <IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;></p>',
+        // @fixme: Is this right?
+        'expected' => 'A hacked image tag: <IMG src="alert(&#039;XSS&#039;)">',
+        'expected_nohtml' => '&lt;p&gt;A hacked image tag: &lt;IMG SRC=&amp;#106;&amp;#97;&amp;#118;&amp;#97;&amp;#115;&amp;#99;&amp;#114;&amp;#105;&amp;#112;&amp;#116;&amp;#58;&amp;#97;&amp;#108;&amp;#101;&amp;#114;&amp;#116;&amp;#40;&amp;#39;&amp;#88;&amp;#83;&amp;#83;&amp;#39;&amp;#41;&gt;&lt;/p&gt;',
+      ),
+    );
+
+    return $htmls;
+  }
 }
