Commit 1607e1bb3805eaca9bc44349202b0d6ec6010fe3

Authored by Antonio Terceiro
Committed by Joenio Costa
1 parent 520af0a8

Fix TextileArticle

  * extract textile to HTML conversion in its own method, which sanitizes
    the generated HTML before returning it.
  * use textile for both the body and the lead.
  * add tests to make sure the textile markup is not being broken.
app/models/textile_article.rb
@@ -9,11 +9,26 @@ class TextileArticle < TextArticle @@ -9,11 +9,26 @@ class TextileArticle < TextArticle
9 end 9 end
10 10
11 def to_html(options ={}) 11 def to_html(options ={})
12 - RedCloth.new(self.body|| '').to_html 12 + convert_to_html(body)
  13 + end
  14 +
  15 + def lead
  16 + if abstract.blank?
  17 + super
  18 + else
  19 + convert_to_html(abstract)
  20 + end
13 end 21 end
14 22
15 def notifiable? 23 def notifiable?
16 true 24 true
17 end 25 end
18 26
  27 + protected
  28 +
  29 + def convert_to_html(textile)
  30 + @@sanitizer ||= HTML::WhiteListSanitizer.new
  31 + @@sanitizer.sanitize(RedCloth.new(textile|| '').to_html)
  32 + end
  33 +
19 end 34 end
test/unit/textile_article_test.rb
@@ -145,4 +145,49 @@ class TextileArticleTest < Test::Unit::TestCase @@ -145,4 +145,49 @@ class TextileArticleTest < Test::Unit::TestCase
145 assert_equal false, a.advertise? 145 assert_equal false, a.advertise?
146 assert_equal false, a.is_trackable? 146 assert_equal false, a.is_trackable?
147 end 147 end
  148 +
  149 + should 'generate proper HTML for links' do
  150 + assert_tag_in_string build_article('"Noosfero":http://noosfero.org/').to_html, :tag => 'a', :attributes => { :href => 'http://noosfero.org/' }
  151 + end
  152 +
  153 + should 'generate proper HTML for > symbols' do
  154 + assert_match /^sqlite>$/, build_article(' sqlite>').to_html
  155 + end
  156 +
  157 + should 'not mess up with textile markup' do
  158 + assert_equal ' sqlite> stuff', build_article(' sqlite> stuff').body
  159 + noosfero_cool = '"Noosfero":http://noosfero.org/ is a very cool project'
  160 + assert_equal noosfero_cool, build_article(noosfero_cool).body
  161 + end
  162 +
  163 + should 'not allow arbitrary HTML' do
  164 + assert_not_equal '<script>alert(1)</script>', build_article('<script>alert(1)</script>').to_html
  165 + end
  166 +
  167 + should 'not allow Javascript on links' do
  168 + assert_no_tag_in_string build_article('<a href="javascript: alert(\'BOOM\')" onclick="javascript: alert(\'BOOM\')"></a>').to_html, :tag => 'a', :attributes => { :href => /./, :onclick => /./ }
  169 + end
  170 +
  171 + should 'allow harmless HTML' do
  172 + code = "<pre><code> code example\n</code></pre>"
  173 + assert_equal code, build_article(code).body
  174 + assert_equal code, build_article(code).to_html
  175 + end
  176 +
  177 + should 'use Textile markup for lead as well' do
  178 + assert_tag_in_string build_article(nil, :abstract => '"Noosfero":http://noosfero.org/').lead, :tag => 'a', :attributes => { :href => 'http://noosfero.org/' }
  179 + end
  180 +
  181 + should 'not allow arbitrary HTML in the lead' do
  182 + assert_not_equal '<script>alert(1)</script>', build_article(nil, :abstract => '<script>alert(1)</script>').lead
  183 + end
  184 +
  185 + protected
  186 +
  187 + def build_article(input = nil, options = {})
  188 + article = TextileArticle.new({:body => input}.merge(options))
  189 + article.valid? # trigger the xss terminate thingy
  190 + article
  191 + end
  192 +
148 end 193 end