Commit 3939a7eb812a8cd7b0c734eed8e2e0d7e804feb8

Authored by Carlos Purificação
Committed by Marcos Pereira
1 parent 5627e255
Exists in new_security

Fixing strings for html_safe

Signed-off-by: Victor Costa <vfcosta@gmail.com>

 Conflicts:
	app/controllers/my_profile/profile_editor_controller.rb
	app/helpers/application_helper.rb
	app/helpers/article_helper.rb
	app/helpers/blog_helper.rb
	app/helpers/boxes_helper.rb
	app/helpers/manage_products_helper.rb
	app/views/account/login.html.erb
	app/views/content_viewer/_article_toolbar.html.erb
	public/designs/themes/base/footer.html.erb
	test/functional/events_controller_test.rb
	test/functional/friends_controller_test.rb
Showing 70 changed files with 277 additions and 217 deletions   Show diff stats
app/controllers/my_profile/cms_controller.rb
... ... @@ -108,7 +108,7 @@ class CmsController &lt; MyProfileController
108 108 end
109 109  
110 110 def new
111   - # FIXME this method should share some logic wirh edit !!!
  111 + # FIXME this method should share some logic with edit !!!
112 112  
113 113 @success_back_to = params[:success_back_to]
114 114 # user must choose an article type first
... ... @@ -370,7 +370,7 @@ class CmsController &lt; MyProfileController
370 370 def search
371 371 query = params[:q]
372 372 results = find_by_contents(:uploaded_files, profile, profile.files.published, query)[:results]
373   - render :text => article_list_to_json(results), :content_type => 'application/json'
  373 + render :text => article_list_to_json(results).html_safe, :content_type => 'application/json'
374 374 end
375 375  
376 376 def search_article_privacy_exceptions
... ...
app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -28,6 +28,7 @@ class ProfileEditorController &lt; MyProfileController
28 28 Image.transaction do
29 29 begin
30 30 @plugins.dispatch(:profile_editor_transaction_extras)
  31 + # TODO: This is unsafe! Add sanitizer
31 32 @profile_data.update!(params[:profile_data])
32 33 redirect_to :action => 'index', :profile => profile.identifier
33 34 rescue Exception => ex
... ...
app/controllers/public/home_controller.rb
... ... @@ -11,7 +11,7 @@ class HomeController &lt; PublicController
11 11 @portal_news = portal_community.news(environment.portal_news_amount, true).offset(environment.highlighted_news_amount)
12 12 @area_news = environment.portal_folders
13 13 end
14   - end
  14 + end
15 15 end
16 16  
17 17 def terms
... ...
app/helpers/application_helper.rb
... ... @@ -91,7 +91,6 @@ module ApplicationHelper
91 91 #
92 92 # TODO: implement correcly the 'Help' button click
93 93 def help(content = nil, link_name = nil, options = {}, &block)
94   -
95 94 link_name ||= _('Help')
96 95  
97 96 @help_message_id ||= 1
... ... @@ -114,7 +113,7 @@ module ApplicationHelper
114 113 button = link_to_function(content_tag('span', link_name), "Element.show('#{help_id}')", options )
115 114 close_button = content_tag("div", link_to_function(_("Close"), "Element.hide('#{help_id}')", :class => 'close_help_button'))
116 115  
117   - text = content_tag('div', button + content_tag('div', content_tag('div', content) + close_button, :class => 'help_message', :id => help_id, :style => 'display: none;'), :class => 'help_box')
  116 + text = content_tag('div', button + content_tag('div', content_tag('div', content.html_safe) + close_button, :class => 'help_message', :id => help_id, :style => 'display: none;'), :class => 'help_box')
118 117  
119 118 unless block.nil?
120 119 concat(text)
... ... @@ -231,9 +230,9 @@ module ApplicationHelper
231 230 end
232 231 the_title = html_options[:title] || label
233 232 if html_options[:disabled]
234   - content_tag('a', '&nbsp;'+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title))
  233 + content_tag('a', '&nbsp;'.html_safe+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title))
235 234 else
236   - link_to('&nbsp;'+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title))
  235 + link_to('&nbsp;'.html_safe+content_tag('span', label), url_for(url).html_safe, html_options.merge(:class => the_class, :title => the_title))
237 236 end
238 237 end
239 238  
... ... @@ -583,8 +582,8 @@ module ApplicationHelper
583 582 def popover_menu(title,menu_title,links,html_options={})
584 583 html_options[:class] = "" unless html_options[:class]
585 584 html_options[:class] << " menu-submenu-trigger"
586   - html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false"
587 585  
  586 + html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false"
588 587 link_to(content_tag(:span, title), '#', html_options)
589 588 end
590 589  
... ... @@ -836,7 +835,7 @@ module ApplicationHelper
836 835 end
837 836 else
838 837 if profile.active_fields.include?(name)
839   - result = content_tag('div', field_html + profile_field_privacy_selector(profile, name), :class => 'field-with-privacy-selector')
  838 + result = content_tag('div', field_html + profile_field_privacy_selector(profile, name), :class => 'field-with-privacy-selector-R1')
840 839 end
841 840 end
842 841  
... ... @@ -1140,7 +1139,8 @@ module ApplicationHelper
1140 1139 end
1141 1140  
1142 1141 def admin_link
1143   - user.is_admin?(environment) ? link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : ''
  1142 + admin_icon = '<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>'
  1143 + user.is_admin?(environment) ? link_to(admin_icon.html_safe, environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : ''
1144 1144 end
1145 1145  
1146 1146 def usermenu_logged_in
... ... @@ -1149,15 +1149,19 @@ module ApplicationHelper
1149 1149 if count > 0
1150 1150 pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks"))
1151 1151 end
1152   -
1153   - (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.url, :id => "homepage-link", :title => _('Go to your homepage'))) +
1154   - render_environment_features(:usermenu) +
1155   - admin_link +
1156   - manage_enterprises +
1157   - manage_communities +
1158   - link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content")) +
1159   - pending_tasks_count +
1160   - link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system"))
  1152 + user_identifier = "<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>"
  1153 + welcome_link = link_to(user_identifier.html_safe, user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage'))
  1154 + welcome_span = _("<span class='welcome'>Welcome,</span> %s") % welcome_link.html_safe
  1155 + ctrl_panel_icon = '<i class="icon-menu-ctrl-panel"></i>'
  1156 + ctrl_panel_section = '<strong>' + ctrl_panel_icon + _('Control panel') + '</strong>'
  1157 + ctrl_panel_link = link_to(ctrl_panel_section.html_safe, user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content"))
  1158 + logout_icon = '<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>'
  1159 + logout_link = link_to(logout_icon.html_safe, { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system"))
  1160 + join_result = safe_join(
  1161 + [welcome_span.html_safe, render_environment_features(:usermenu).html_safe, admin_link.html_safe,
  1162 + manage_enterprises.html_safe, manage_communities.html_safe, ctrl_panel_link.html_safe,
  1163 + pending_tasks_count.html_safe, logout_link.html_safe], "")
  1164 + join_result
1161 1165 end
1162 1166  
1163 1167 def usermenu_notlogged_in
... ... @@ -1272,8 +1276,8 @@ module ApplicationHelper
1272 1276 end
1273 1277  
1274 1278 def render_tabs(tabs)
1275   - titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
1276   - contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
  1279 + titles = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
  1280 + contents = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
1277 1281  
1278 1282 content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs')
1279 1283 end
... ... @@ -1291,7 +1295,7 @@ module ApplicationHelper
1291 1295 def expirable_link_to(expired, content, url, options = {})
1292 1296 if expired
1293 1297 options[:class] = (options[:class] || '') + ' disabled'
1294   - content_tag('a', '&nbsp;'+content_tag('span', content), options)
  1298 + content_tag('a', '&nbsp;'.html_safe+content_tag('span', content), options)
1295 1299 else
1296 1300 if options[:modal]
1297 1301 options.delete(:modal)
... ... @@ -1387,7 +1391,8 @@ module ApplicationHelper
1387 1391 # are old things that do not support it we are keeping this hot spot.
1388 1392 html = @plugins.pipeline(:parse_content, html, source).first
1389 1393 end
1390   - html && html.html_safe
  1394 +
  1395 + html.html_safe && html
1391 1396 end
1392 1397  
1393 1398 def convert_macro(html, source)
... ...
app/helpers/article_helper.rb
... ... @@ -10,52 +10,61 @@ module ArticleHelper
10 10  
11 11 def custom_options_for_article(article, tokenized_children)
12 12 @article = article
13   -
14   - visibility_options(@article, tokenized_children) +
15   - topic_creation(@article) +
16   - content_tag('h4', _('Options')) +
17   - content_tag('div',
18   - (article.profile.has_members? ?
  13 + opts = visibility_options(@article, tokenized_children)
  14 + ret = opts
  15 + ret << content_tag('h4', _('Options'))
  16 + inner = "".html_safe
  17 + inner << (article.profile.has_members? ?
19 18 content_tag(
20 19 'div',
21 20 check_box(:article, :allow_members_to_edit) +
22 21 content_tag('label', _('Allow all members to edit this article'), :for => 'article_allow_members_to_edit')
23 22 ) :
24   - '') +
25   -
  23 + '')
  24 + inner <<
  25 + (article.parent && article.parent.forum? && controller.action_name == 'new' ?
  26 + hidden_field_tag('article[accept_comments]', 1) :
26 27 content_tag(
27 28 'div',
28 29 check_box(:article, :accept_comments) +
29 30 content_tag('label', (article.parent && article.parent.forum? ? _('This topic is opened for replies') : _('I want to receive comments about this article')), :for => 'article_accept_comments')
30   - ) +
31   -
  31 + ))
  32 + inner <<
32 33 content_tag(
33 34 'div',
34 35 check_box(:article, :notify_comments) +
35 36 content_tag('label', _('I want to receive a notification of each comment written by e-mail'), :for => 'article_notify_comments') +
36 37 observe_field(:article_accept_comments, :function => "jQuery('#article_notify_comments')[0].disabled = ! jQuery('#article_accept_comments')[0].checked;jQuery('#article_moderate_comments')[0].disabled = ! jQuery('#article_accept_comments')[0].checked")
37   - ) +
38   -
  38 + )
  39 + inner <<
39 40 content_tag(
40 41 'div',
41 42 check_box(:article, :moderate_comments) +
42 43 content_tag('label', _('I want to approve comments on this article'), :for => 'article_moderate_comments')
43   - ) +
44   -
  44 + )
  45 + inner <<
45 46 (article.can_display_hits? ?
46 47 content_tag(
47 48 'div',
48 49 check_box(:article, :display_hits) +
49 50 content_tag('label', _('I want this article to display the number of hits it received'), :for => 'article_display_hits')
50   - ) : '') +
51   -
  51 + ) : '')
  52 + inner <<
52 53 (article.can_display_versions? ?
53 54 content_tag(
54 55 'div',
55 56 check_box(:article, :display_versions) +
56 57 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
57 58 ) : '')
58   - )
  59 + inner <<
  60 + (article.forum? && article.profile.community? ?
  61 + content_tag(
  62 + 'div',
  63 + check_box(:article, :allows_members_to_create_topics) +
  64 + content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics')
  65 + ) : '')
  66 + ret << content_tag('div', inner)
  67 + ret
59 68 end
60 69  
61 70 def visibility_options(article, tokenized_children)
... ... @@ -107,7 +116,7 @@ module ArticleHelper
107 116 def add_option_to_followers(article, tokenized_children)
108 117 label_message = article.profile.organization? ? _('Allow all community members to view this content') : _('Allow all your friends to view this content')
109 118  
110   - check_box(
  119 + ret = check_box(
111 120 :article,
112 121 :show_to_followers,
113 122 {:class => "custom_privacy_option"}
... ... @@ -137,6 +146,7 @@ module ArticleHelper
137 146 }
138 147 )
139 148 ) : '')
  149 + ret
140 150 end
141 151  
142 152 def prepare_to_token_input(array)
... ...
app/helpers/block_helper.rb
1 1 module BlockHelper
2 2  
3 3 def block_title(title)
4   - tag_class = 'block-title'
  4 + tag_class = 'block-title'.html_safe
5 5 tag_class += ' empty' if title.empty?
6 6 content_tag 'h3', content_tag('span', h(title)), :class => tag_class
7 7 end
... ...
app/helpers/blog_helper.rb
... ... @@ -46,7 +46,7 @@ module BlogHelper
46 46 end
47 47 end)
48 48 }
49   - content.join("\n<hr class='sep-posts'/>\n") + (pagination or '')
  49 + safe_join(content, "\n<hr class='sep-posts'/>\n") + (pagination or '').html_safe
50 50 end
51 51  
52 52 def display_post(article, format = 'full')
... ... @@ -61,7 +61,8 @@ module BlogHelper
61 61 else
62 62 '<div class="post-pic" style="background-image:url('+img+')"></div>'
63 63 end
64   - end.to_s + title + html
  64 + end.to_s.html_safe +
  65 + title.html_safe + html
65 66 end
66 67  
67 68 def display_compact_format(article)
... ...
app/helpers/boxes_helper.rb
... ... @@ -44,7 +44,7 @@ module BoxesHelper
44 44  
45 45 def display_boxes(holder, main_content)
46 46 boxes = holder.boxes.with_position.first(boxes_limit(holder))
47   - content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n")
  47 + content = safe_join(boxes.reverse.map { |item| display_box(item, main_content) }, "\n")
48 48 content = main_content if (content.blank?)
49 49  
50 50 content_tag('div', content, :class => 'boxes', :id => 'boxes' )
... ... @@ -54,7 +54,7 @@ module BoxesHelper
54 54 if holder.respond_to?(element)
55 55 content_tag('div', holder.send(element), options)
56 56 else
57   - ''
  57 + ''.html_safe
58 58 end
59 59 end
60 60  
... ... @@ -70,9 +70,10 @@ module BoxesHelper
70 70  
71 71 def display_box_content(box, main_content)
72 72 context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user, :controller => controller }
73   - box_decorator.select_blocks(box, box.blocks.includes(:box), context).map do |item|
  73 + blocks = box_decorator.select_blocks(box, box.blocks.includes(:box), context).map do |item|
74 74 display_block item, main_content
75   - end.join("\n") + box_decorator.block_target(box)
  75 + end
  76 + safe_join(blocks, "\n") + box_decorator.block_target(box)
76 77 end
77 78  
78 79 def select_blocks box, arr, context
... ... @@ -88,7 +89,13 @@ module BoxesHelper
88 89 end
89 90  
90 91 def display_block_content(block, person, main_content = nil)
91   - content = block.main? ? wrap_main_content(main_content) : block.content({:person => person})
  92 + if block.main? then
  93 + content = wrap_main_content(main_content)
  94 + else
  95 + content = block.content({:person => person})
  96 + end
  97 + #content = block.main? ? wrap_main_content(main_content) : block.content({:person => person})
  98 +
92 99 result = extract_block_content(content)
93 100 footer_content = extract_block_content(block.footer)
94 101 unless footer_content.blank?
... ... @@ -108,17 +115,18 @@ module BoxesHelper
108 115  
109 116 result = filter_html(result, block)
110 117  
111   - content_tag('div',
112   - box_decorator.block_target(block.box, block) +
113   - content_tag('div',
114   - content_tag('div',
115   - content_tag('div',
116   - result + footer_content + box_decorator.block_edit_buttons(block),
117   - :class => 'block-inner-2'),
118   - :class => 'block-inner-1'),
119   - options),
120   - :class => 'block-outer') +
121   - box_decorator.block_handle(block)
  118 + join_result = safe_join([result, footer_content, box_decorator.block_edit_buttons(block)])
  119 + content_tag_inner_1 = content_tag('div', join_result, :class => 'block-inner-2')
  120 +
  121 + content_tag_inner_2 = content_tag('div', content_tag_inner_1, :class => 'block-inner-1')
  122 + content_tag_inner_3 = content_tag('div', content_tag_inner_2, options)
  123 + content_tag_inner_4 = box_decorator.block_target(block.box, block) + content_tag_inner_3
  124 + c = content_tag('div', content_tag_inner_4, :class => 'block-outer')
  125 + box_decorator_result = box_decorator.block_handle(block)
  126 + result_final = safe_join([c, box_decorator_result], "")
  127 +
  128 +
  129 + return result_final
122 130 end
123 131  
124 132 def wrap_main_content(content)
... ... @@ -128,17 +136,17 @@ module BoxesHelper
128 136 def extract_block_content(content)
129 137 case content
130 138 when Hash
131   - content_tag('iframe', '', :src => url_for(content))
  139 + content_tag('iframe', ''.html_safe, :src => url_for(content))
132 140 when String
133 141 if content.split("\n").size == 1 and content =~ /^https?:\/\//
134   - content_tag('iframe', '', :src => content)
  142 + content_tag('iframe', ''.html_safe, :src => content)
135 143 else
136 144 content
137 145 end
138 146 when Proc
139 147 self.instance_eval(&content)
140 148 when NilClass
141   - ''
  149 + ''.html_safe
142 150 else
143 151 raise "Unsupported content for block (#{content.class})"
144 152 end
... ... @@ -147,14 +155,14 @@ module BoxesHelper
147 155 module DontMoveBlocks
148 156 # does nothing
149 157 def self.block_target(box, block = nil)
150   - ''
  158 + ''.html_safe
151 159 end
152 160 # does nothing
153 161 def self.block_handle(block)
154   - ''
  162 + ''.html_safe
155 163 end
156 164 def self.block_edit_buttons(block)
157   - ''
  165 + ''.html_safe
158 166 end
159 167 def self.select_blocks box, arr, context
160 168 arr = arr.select{ |block| block.visible? context }
... ... @@ -201,9 +209,9 @@ module BoxesHelper
201 209 # makes the given block draggable so it can be moved away.
202 210 def block_handle(block)
203 211 return "" unless movable?(block)
204   - icon = "<div><div>#{display_icon(block.class)}</div><span>#{_(block.class.pretty_name)}</span></div>"
  212 + icon = "<div><div>#{display_icon(block.class)}</div><span>#{_(block.class.pretty_name)}</span></div>".html_safe
205 213 block_draggable("block-#{block.id}",
206   - :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}")
  214 + :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}".html_safe)
207 215 end
208 216  
209 217 def block_draggable(element_id, options={})
... ...
app/helpers/catalog_helper.rb
... ... @@ -19,7 +19,7 @@ module CatalogHelper
19 19 ancestors = category.ancestors.map { |c| link_to(c.name, {:controller => :catalog, :action => 'index', :level => c.id}) }.reverse
20 20 current_level = content_tag('strong', category.name)
21 21 all_items = [start] + ancestors + [current_level]
22   - content_tag('div', all_items.join(' &rarr; '), :id => 'breadcrumb')
  22 + content_tag('div', safe_join(all_items, ' &rarr; '), :id => 'breadcrumb')
23 23 end
24 24  
25 25 def category_link(category)
... ...
app/helpers/display_helper.rb
... ... @@ -53,18 +53,19 @@ module DisplayHelper
53 53 end
54 54  
55 55 def txt2html(txt)
56   - txt.strip.
  56 + ret = txt.strip.
57 57 gsub( /\s*\n\s*\n\s*/, "\r<p/>\r" ).
58 58 gsub( /\s*\n\s*/, "\n<br/>\n" ).
59 59 gsub( /\r/, "\n" ).
60 60 gsub( /(^|\s)(www\.[^\s]+|https?:\/\/[^\s]+)/ ) do
61 61 pre_char, href = $1, $2
62 62 href = 'http://'+href if ! href.match /^https?:/
63   - content = href.gsub(/^https?:\/\//, '').scan(/.{1,4}/).join('&#x200B;')
  63 + content = safe_join(href.gsub(/^https?:\/\//, '').scan(/.{1,4}/), '&#x200B;'.html_safe)
64 64 pre_char +
65 65 content_tag(:a, content, :href => href, :target => '_blank',
66 66 :rel => 'nofolow', :onclick => "return confirm('%s')" %
67 67 _('Are you sure you want to visit this web site?'))
68 68 end
  69 + ret.html_safe
69 70 end
70 71 end
... ...
app/helpers/events_helper.rb
... ... @@ -3,11 +3,13 @@ module EventsHelper
3 3 include DatesHelper
4 4 def list_events(date, events)
5 5 title = _('Events for %s') % show_date_month(date)
  6 + user_events = events.select { |item| item.display_to?(user) }
  7 + events_for_month = safe_join(user_events.map {|item| display_event_in_listing(item)}, '')
6 8 content_tag('h2', title) +
7 9 content_tag('div',
8 10 (events.any? ?
9   - content_tag('table', events.select { |item| item.display_to?(user) }.map {|item| display_event_in_listing(item)}.join('')) :
10   - content_tag('em', _('No events for this month'), :class => 'no-events')
  11 + content_tag('table', events_for_month) :
  12 + content_tag('em', _('No events for this month'), :class => 'no-events')
11 13 ), :id => 'agenda-items'
12 14 )
13 15 end
... ...
app/helpers/forms_helper.rb
... ... @@ -111,10 +111,11 @@ module FormsHelper
111 111 options_for_select = container.inject([]) do |options, element|
112 112 text, value = option_text_and_value(element)
113 113 selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
114   - options << %(<option title="#{html_escape(text.to_s)}" value="#{html_escape(value.to_s)}"#{selected_attribute}>#{html_escape(text.to_s)}</option>)
  114 + opt = %(<option title="#{html_escape(text.to_s)}" value="#{html_escape(value.to_s)}"#{selected_attribute}>#{html_escape(text.to_s)}</option>)
  115 + options << opt.html_safe
115 116 end
116 117  
117   - options_for_select.join("\n")
  118 + safe_join(options_for_select, "\n")
118 119 end
119 120  
120 121 def balanced_table(items, per_row=3)
... ...
app/helpers/forum_helper.rb
... ... @@ -35,7 +35,7 @@ module ForumHelper
35 35 :id => "post-#{art.id}"
36 36 )
37 37 }
38   - content_tag('table', content.join) + (pagination or '')
  38 + content_tag('table', safe_join(content, "")) + (pagination or '').html_safe
39 39 end
40 40  
41 41 def last_topic_update(article)
... ...
app/helpers/manage_products_helper.rb
... ... @@ -38,10 +38,11 @@ module ManageProductsHelper
38 38 end
39 39  
40 40 def options_for_select_categories(categories, selected = nil)
41   - categories.sort_by{|cat| cat.name.transliterate}.map do |category|
42   - selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '')
43   - "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{category.name + (category.leaf? ? '': ' &raquo;')}</option>"
44   - end.join("\n")
  41 + safe_join(categories.sort_by{ |cat|
  42 + cat.name.transliterate}.map do |category|
  43 + selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '')
  44 + "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{category.name + (category.leaf? ? '': ' &raquo;')}</option>".html_safe
  45 + end, "\n")
45 46 end
46 47  
47 48 def build_selects_for_ancestors(ancestors, current_category)
... ... @@ -76,10 +77,13 @@ module ManageProductsHelper
76 77  
77 78 def categories_container(categories_selection_html, hierarchy_html = '')
78 79 content_tag 'div',
79   - render('categories_autocomplete') +
80   - hidden_field_tag('selected_category_id') +
81   - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +
82   - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'),
  80 + safe_join(
  81 + [
  82 + render('categories_autocomplete'),
  83 + hidden_field_tag('selected_category_id'),
  84 + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation'),
  85 + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper')
  86 + ], ''),
83 87 :id => 'categories-container'
84 88 end
85 89  
... ...
app/helpers/profile_editor_helper.rb
... ... @@ -129,7 +129,11 @@ module ProfileEditorHelper
129 129 else
130 130 domains = environment.domains
131 131 end
132   - labelled_form_field(_('Preferred domain name:'), select(object, :preferred_domain_id, domains.map {|item| [item.name, item.id]}, :prompt => '&lt;' + _('Select domain') + '&gt;'))
  132 + select_domain_prompt = '&lt;'.html_safe + _('Select domain').html_safe + '&gt;'.html_safe
  133 + select_field = select(object, :preferred_domain_id, domains.map {
  134 + |item| [item.name, item.id]}, :prompt => select_domain_prompt.html_safe)
  135 +
  136 + labelled_form_field(_('Preferred domain name:'), select_field)
133 137 end
134 138  
135 139 def control_panel(&block)
... ...
app/helpers/search_helper.rb
... ... @@ -124,10 +124,10 @@ module SearchHelper
124 124 def filters(asset)
125 125 return if !asset
126 126 klass = asset_class(asset)
127   - content_tag('div', klass::SEARCH_FILTERS.map do |name, options|
  127 + content_tag('div', safe_join(klass::SEARCH_FILTERS.map do |name, options|
128 128 default = klass.respond_to?("default_search_#{name}") ? klass.send("default_search_#{name}".to_s) : nil
129 129 select_filter(name, options, default)
130   - end.join("\n"), :id => 'search-filters')
  130 + end, "\n"), :id => 'search-filters')
131 131 end
132 132  
133 133 def assets_menu(selected)
... ... @@ -137,11 +137,11 @@ module SearchHelper
137 137 # menu.
138 138 assets.delete(:events)
139 139 content_tag('ul',
140   - assets.map do |asset|
  140 + safe_join(assets.map do |asset|
141 141 options = {}
142 142 options.merge!(:class => 'selected') if selected.to_s == asset.to_s
143 143 content_tag('li', asset_link(asset), options)
144   - end.join("\n"),
  144 + end, "\n"),
145 145 :id => 'assets-menu')
146 146 end
147 147  
... ...
app/models/blog_archives_block.rb
... ... @@ -40,6 +40,7 @@ class BlogArchivesBlock &lt; Block
40 40 end
41 41 results << "</ul>"
42 42 end
  43 + results.html_safe
43 44 block_title(title) +
44 45 content_tag('ul', results, :class => 'blog-archives') +
45 46 content_tag('div', link_to(_('Subscribe RSS Feed'), owner_blog.feed.url), :class => 'subscribe-feed')
... ...
app/models/link_list_block.rb
... ... @@ -60,17 +60,20 @@ class LinkListBlock &lt; Block
60 60 end
61 61  
62 62 def content(args={})
63   - block_title(title) +
64   - content_tag('ul',
65   - links.select{|i| !i[:name].blank? and !i[:address].blank?}.map{|i| content_tag('li', link_html(i))}.join
66   - )
  63 + ret = "".html_safe
  64 + ret = ret + block_title(title)
  65 + selected_links = links.select{ |i| !i[:name].blank? and !i[:address].blank? }
  66 + ret_links = selected_links.map { |i| content_tag('li', link_html(i).html_safe) }
  67 + inner_join = ret_links.join.html_safe
  68 + return ret + content_tag('ul', inner_join)
67 69 end
68 70  
69 71 def link_html(link)
70 72 klass = 'icon-' + link[:icon] if link[:icon]
71   - sanitize_link(
  73 + sanitized_link = sanitize_link(
72 74 link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass, :title => link[:title])
73 75 )
  76 + return sanitized_link
74 77 end
75 78  
76 79 def expand_address(address)
... ...
app/models/products_block.rb
... ... @@ -20,19 +20,17 @@ class ProductsBlock &lt; Block
20 20 end
21 21  
22 22 def content(args={})
23   - block_title(title) +
24   - content_tag(
25   - 'ul',
26   - products.map {|product|
27   - content_tag('li',
28   - link_to( product.name,
29   - product.url,
30   - :style => 'background-image:url(%s)' % product.default_image('minor')
31   - ),
32   - :class => 'product'
  23 + product_title = block_title(title).html_safe
  24 + products_map = products.map { |product|
  25 + product_link = link_to(
  26 + product.name,
  27 + product.url,
  28 + :style => 'background-image:url(%s)' % product.default_image('minor')
33 29 )
34   - }.join
35   - )
  30 + content_tag('li', product_link.html_safe, :class => 'product')
  31 + }
  32 + products_map_join = products_map.join.html_safe
  33 + product_title.html_safe + content_tag('ul', products_map_join)
36 34 end
37 35  
38 36 def footer
... ...
app/models/profile_list_block.rb
... ... @@ -42,14 +42,14 @@ result = public_profiles.all(:limit =&gt; get_limit, :order =&gt; &#39;profiles.updated_at
42 42  
43 43 def content(args={})
44 44 profiles = self.profile_list
45   - title = self.view_title
46   - nl = "\n"
  45 + title = self.view_title.html_safe
  46 + nl = "\n".html_safe
47 47 proc do |context|
48 48 count=0
49   - list = profiles.map {|item|
  49 + list = safe_join(profiles.map {|item|
50 50 count+=1
51 51 send(:profile_image_link, item, :minor )
52   - }.join("\n ")
  52 + }, "\n ")
53 53 if list.empty?
54 54 list = content_tag 'div', _('None'), :class => 'common-profile-list-block-none'
55 55 else
... ...
app/models/recent_documents_block.rb
... ... @@ -26,8 +26,12 @@ class RecentDocumentsBlock &lt; Block
26 26 docs = self.docs
27 27 title = self.title
28 28 proc do
29   - block_title(title) +
30   - content_tag('ul', docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n"))
  29 + docsmap = safe_join(docs.map { |item|
  30 + content_tag('li',
  31 + link_to( h(item.title), item.url)
  32 + )
  33 + }, "\n")
  34 + block_title(title) + content_tag('ul', docsmap)
31 35 end
32 36 end
33 37  
... ...
app/models/tags_block.rb
... ... @@ -43,10 +43,10 @@ class TagsBlock &lt; Block
43 43 owner.public_profile_url.merge(:controller => 'profile', :action => 'content_tagged')
44 44 tagname_option = is_env ? :tag : :id
45 45  
46   - block_title(title) +
  46 + (block_title(title) +
47 47 "\n<div class='tag_cloud'>\n".html_safe+
48 48 tag_cloud( tags, tagname_option, url, :max_size => 16, :min_size => 9 ) +
49   - "\n</div><!-- end class='tag_cloud' -->\n".html_safe
  49 + "\n</div><!-- end class='tag_cloud' -->\n").html_safe
50 50 end
51 51  
52 52 def footer
... ...
app/views/account/_signup_form.html.erb
... ... @@ -107,7 +107,7 @@
107 107 <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %>
108 108 <% end %>
109 109  
110   - <%= @plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
  110 + <%= safe_join(@plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }, "") %>
111 111  
112 112 <%= template_options(:people, 'profile_data') %>
113 113  
... ...
app/views/account/login.html.erb
... ... @@ -20,7 +20,7 @@
20 20 </label>
21 21 </div>
22 22  
23   - <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_exec(&content) }.join("") %>
  23 + <%= safe_join(@plugins.dispatch(:login_extra_contents).collect { |content| instance_exec(&content) }, "") %>
24 24  
25 25 <% button_bar do %>
26 26 <%= submit_button( 'login', _('Log in') )%>
... ...
app/views/account/login_block.html.erb
... ... @@ -15,7 +15,7 @@
15 15  
16 16 <%= f.password_field :password %>
17 17  
18   - <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
  18 + <%= safe_join(@plugins.dispatch(:login_extra_contents).collect { |content| instance_eval(&content) }, "") %>
19 19  
20 20 <% button_bar do %>
21 21 <%= submit_button( 'login', _('Log in') )%>
... ...
app/views/blocks/login_block.html.erb
... ... @@ -3,7 +3,7 @@
3 3 <h2><%= _('Logged in as %s') % user.identifier %></h2>
4 4 <ul>
5 5 <li><%= _('User since %s/%s') % [user.created_at.month, user.created_at.year] %></li>
6   - <li><%= link_to _('Homepage'), user.public_profile_url %></li>
  6 + <li><%= link_to _('Homepage'), url_for(user.public_profile_url) %></li>
7 7 </ul>
8 8 <div class="user-actions">
9 9 <%= button(:'menu-logout', _('Logout'), :controller => 'account', :action => 'logout') %>
... ...
app/views/box_organizer/_article_block.html.erb
... ... @@ -9,7 +9,8 @@
9 9 first_text = articles[articles.find_index{|a| a.kind_of? TextArticle}||-1]
10 10 selected = @block.article || first_text
11 11 %>
12   - <%= select_tag(
  12 + <%=
  13 + select_tag(
13 14 'block[article_id]',
14 15 options_for_select_with_title(articles.map {|item| [item.path, item.id]}, selected.id),
15 16 :onchange => 'this.changedTo(this.value)'
... ...
app/views/catalog/index.html.erb
... ... @@ -35,7 +35,7 @@
35 35 <% else %>
36 36 <div class="no-image"><%= _('No image') %></div>
37 37 <% end %>
38   - <div class="catalog-item-extras"><%= extra_content.join("\n") %></div>
  38 + <div class="catalog-item-extras"><%= safe_join(extra_content, "\n") %></div>
39 39 </li>
40 40  
41 41 <li class="product-link"><%= link_to_product product %></li>
... ...
app/views/cms/select_article_type.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <ul class="article-types">
6 6 <% for type in @article_types %>
7 7 <% action = type[:class].name == 'UploadedFile' ? {:action => 'upload_files'} : {:action => 'new', :type => type[:class].name} %>
8   - <%= content_tag('a', :href => url_for(action.merge(:parent_id => @parent_id, :back_to => @back_to))) do %>
  8 + <%= content_tag('a', :href => url_for(action.merge(:parent_id => @parent_id, :back_to => @back_to)).html_safe) do %>
9 9 <li class="<%= icon_for_new_article(type[:class]) %>" onmouseover="javascript: jQuery(this).addClass('mouseover')" onmouseout="jQuery(this).removeClass('mouseover')">
10 10 <strong><%= type[:short_description] %></strong>
11 11 <div class='description'><%= type[:description] %></div>
... ...
app/views/cms/upload_files.html.erb
... ... @@ -17,11 +17,11 @@
17 17 <h3><%= _("Select the files you want to upload (max size %s):") % UploadedFile.max_size.to_humanreadable %></h3>
18 18 <h4><%= _('Documents, Images, Videos, Audio') %></h4>
19 19  
20   -<h5><%= _('Uploading files to %s') % content_tag('code', @target) %></h5>
  20 +<h5><%= (_('Uploading files to %s') % content_tag('code', @target)).html_safe%></h5>
21 21  
22 22 <%= form_for('uploaded_file', :url => { :action => 'upload_files' }, :html => {:multipart => true}) do |f| %>
23 23  
24   - <%= @plugins.dispatch(:upload_files_extra_fields, params[:parent_id]).collect { |content| instance_exec(&content) }.join("") %>
  24 + <%= safe_join(@plugins.dispatch(:upload_files_extra_fields, params[:parent_id]).collect { |content| instance_exec(&content) }, "") %>
25 25  
26 26 <%= render :partial => 'upload_file_form', :locals => { :size => '45'} %>
27 27  
... ...
app/views/cms/view.html.erb
... ... @@ -26,7 +26,7 @@
26 26 <strong><%= _('Current folder: ') %></strong>
27 27 <%= link_to profile.identifier, :action => 'index' %>
28 28 <% @article.hierarchy.each do |item| %>
29   - <%= " / " + ((item == @article) ? item.name.html_safe : link_to(item.slug, :id => item.id).html_safe) %>
  29 + <%= " / ".html_safe + ((item == @article) ? item.name.html_safe : link_to(item.slug, :id => item.id).html_safe) %>
30 30 <% end %>
31 31 </div>
32 32 <% end %>
... ... @@ -45,9 +45,9 @@
45 45 <tr>
46 46 <td>
47 47 <% if @article.parent %>
48   - <%= link_to '.. (' + _('parent folder') + ')', {:action => 'view', :id => @article.parent.id}, :class => 'icon-parent-folder' %>
  48 + <%= link_to '.. ('.html_safe + _('parent folder') + ')', {:action => 'view', :id => @article.parent.id}, :class => 'icon-parent-folder' %>
49 49 <% else %>
50   - <%= link_to '.. (' + _('parent folder') + ')', {:action => 'index'}, :class => 'icon-parent-folder' %>
  50 + <%= link_to '.. ('.html_safe + _('parent folder') + ')', {:action => 'index'}, :class => 'icon-parent-folder' %>
51 51 <% end %>
52 52 </td>
53 53 <td><%= Folder.short_description %></td>
... ...
app/views/comment/_comment.html.erb
... ... @@ -43,7 +43,7 @@
43 43 <p/>
44 44 <%= txt2html comment.body %>
45 45 </div>
46   - <%= @plugins.dispatch(:comment_extra_contents, local_assigns).collect { |content| instance_exec(&content) }.join("") %>
  46 + <%= safe_join(@plugins.dispatch(:comment_extra_contents, local_assigns).collect { |content| instance_exec(&content) }, "") %>
47 47 </div>
48 48  
49 49 <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>">
... ...
app/views/comment/_comment_form.html.erb
... ... @@ -85,7 +85,7 @@ function check_captcha(button, confirm_action) {
85 85 <%= hidden_field_tag(:view, params[:view])%>
86 86 <%= f.hidden_field(:reply_of_id) %>
87 87  
88   - <%= @plugins.dispatch(:comment_form_extra_contents, local_assigns.merge(:comment => @comment)).collect { |content| instance_exec(&content) }.join("") %>
  88 + <%= safe_join(@plugins.dispatch(:comment_form_extra_contents, local_assigns.merge(:comment => @comment)).collect { |content| instance_exec(&content) }, "") %>
89 89  
90 90 <% button_bar do %>
91 91 <%= submit_button('add', _('Post comment'), :onclick => "if(check_captcha(this)) { save_comment(this) } else { check_captcha(this, save_comment)};return false;") %>
... ...
app/views/content_viewer/_article_toolbar.html.erb
... ... @@ -26,7 +26,7 @@
26 26 <% content = _('Add translation') %>
27 27 <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %>
28 28 <% url = profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => parent_id, :type => @page.type, :article => { :translation_of_id => @page.native_translation.id })%>
29   - <%= expirable_button @page, :locale, content, url %>
  29 + <%= expirable_button @page, :locale, content, url_for(url).html_safe %>
30 30 <% end %>
31 31  
32 32 <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %>
... ... @@ -64,9 +64,9 @@
64 64 <% if @page.blog? and !@page.image.nil? %>
65 65 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div>
66 66 <% end %>
67   - <%= button_without_text(:feed, _('RSS feed'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
68   - <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
69   - <%= render :partial => 'article_title', :locals => {:no_link => true} %>
  67 + <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
  68 + <%= safe_join(@plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) },"") %>
  69 + <%= article_title(@page, :no_link => true) %>
70 70 <%= article_translations(@page) %>
71 71 </div>
72 72 </div>
... ...
app/views/content_viewer/versions_diff.html.erb
... ... @@ -2,9 +2,9 @@
2 2 <%= button(:back, _('Back to the versions'), {:action => 'article_versions'}) %>
3 3 </div>
4 4  
5   -<h1><%= _('Changes on "%s"') % @page.title %></h1>
  5 +<h1><%= _('Changes on "%s"').html_safe % @page.title %></h1>
6 6  
7   -<p> <%= _('Changes from %s &rarr; %s') % [show_time(@v1.updated_at), show_time(@v2.updated_at)] %> </p>
  7 +<p> <%= _('Changes from %s &rarr; %s').html_safe % [show_time(@v1.updated_at), show_time(@v2.updated_at)] %> </p>
8 8  
9 9 <% diffContent = Diffy::Diff.new(@v1.body, @v2.body, :context => 1) %>
10 10 <% if diffContent.to_s(:text).blank? %>
... ... @@ -12,5 +12,5 @@
12 12 <%= _('These versions range have no differences.')%>
13 13 </p>
14 14 <% else %>
15   - <%= diffContent.to_s(:html) %>
  15 + <%= diffContent.to_s(:html).html_safe %>
16 16 <% end %>
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -45,20 +45,20 @@
45 45 <% if ! @page.categories.empty? %>
46 46 <div id="article-cat">
47 47 <h4><%= _('Categories') %></h4>
48   - <%= @page.categories.map {|item| link_to_category(item, false) }.join(", ") %>
  48 + <%= safe_join(@page.categories.map {|item| link_to_category(item, false) }, ", ") %>
49 49 </div>
50 50 <% end %>
51 51  
52 52 <% if !@page.tags.empty? %>
53 53 <div id="article-tags">
54   - <%= _("This article's tags:") %>
55   - <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
  54 + <%= _("This article's tags:").html_safe %>
  55 + <%= safe_join(@page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }, "\n") %>
56 56 </div>
57 57 <% end %>
58 58  
59 59 <%= display_source_info(@page) %>
60 60  
61   -<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
  61 +<%= safe_join(@plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_exec(&content) }, "") %>
62 62  
63 63 <% if @page.accept_comments? || @comments_count > 0 %>
64 64 <div class="comments" id="comments_list">
... ...
app/views/home/index.html.erb
... ... @@ -49,7 +49,7 @@
49 49 <% end %>
50 50 <% end %>
51 51 <% else %>
52   - <%= environment.description %>
  52 + <%= environment.description.html_safe %>
53 53 <% end %>
54 54  
55 55 <% if environment.enabled?('search_in_home') %>
... ...
app/views/invite/_select_address_book.html.erb
... ... @@ -3,12 +3,12 @@
3 3  
4 4 <%= form_tag do %>
5 5  
6   - <%= [
  6 + <%= safe_join([
7 7 radio_button_tag(:import_from, "manual", @import_from == "manual", :onclick => 'hide_invite_friend_login_password()') + content_tag('label', _('Manually (empty field)'), :for => "import_from_manual"),
8 8 radio_button_tag(:import_from, "gmail", @import_from == "gmail", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Gmail', :for => 'import_from_gmail'),
9 9 radio_button_tag(:import_from, "yahoo", @import_from == "yahoo", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Yahoo', :for => "import_from_yahoo"),
10 10 radio_button_tag(:import_from, "hotmail", @import_from == "hotmail", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Hotmail', :for => "import_from_hotmail")
11   - ].join("\n<br/>\n") %>
  11 + ], "\n<br/>\n") %>
12 12  
13 13 <script type="text/javascript">
14 14 function hide_invite_friend_login_password() {
... ...
app/views/layouts/application-ng.html.erb
... ... @@ -20,9 +20,14 @@
20 20 <%# Add custom tags/styles/etc via content_for %>
21 21 <%= yield :head %>
22 22 <%=
23   - @plugins.dispatch(:head_ending).map do |content|
24   - if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end
25   - end.join("\n")
  23 + str = (@plugins.dispatch(:head_ending).map do |content|
  24 + if content.respond_to?(:call) then
  25 + instance_exec(&content).to_s
  26 + else
  27 + content.to_s
  28 + end
  29 + end)
  30 + safe_join(str, "\n")
26 31 %>
27 32  
28 33 <script type="text/javascript">
... ... @@ -33,11 +38,15 @@
33 38 </head>
34 39 <body class="<%= h body_classes %>">
35 40 <a href="#content" id="link-go-content"><span><%= _("Go to the content") %></span></a>
36   -
37 41 <%=
38   - @plugins.dispatch(:body_beginning).map do |content|
39   - if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end
40   - end.join("\n")
  42 + str = (@plugins.dispatch(:body_beginning).map do |content|
  43 + if content.respond_to?(:call) then
  44 + instance_exec(&content).to_s
  45 + else
  46 + content.to_s
  47 + end
  48 + end)
  49 + safe_join(str, "\n")
41 50 %>
42 51 <div id="global-header">
43 52 <%= global_header %>
... ... @@ -75,9 +84,14 @@
75 84 <%= noosfero_layout_features %>
76 85 <%= addthis_javascript %>
77 86 <%=
78   - @plugins.dispatch(:body_ending).map do |content|
79   - if content.respond_to?(:call) then instance_exec(&content).html_safe else content.html_safe end
80   - end.join("\n")
  87 + str = (@plugins.dispatch(:body_ending).map do |content|
  88 + if content.respond_to?(:call) then
  89 + instance_exec(&content)
  90 + else
  91 + content
  92 + end
  93 + end)
  94 + safe_join(str, "\n")
81 95 %>
82 96 </body>
83 97 </html>
... ...
app/views/mailconf/index.html.erb
... ... @@ -16,7 +16,7 @@
16 16 <% if profile.user.enable_email %>
17 17 <h2><%= ('E-mail address') %></h2>
18 18 <ul>
19   - <%= profile.email_addresses.map{|i| content_tag('li', i)}.join("\n") %>
  19 + <%= safe_join(profile.email_addresses.map{|i| content_tag('li', i)}, "\n") %>
20 20 </ul>
21 21 <h2><%= _('Configuration') %></h2>
22 22 <ul>
... ... @@ -31,7 +31,7 @@
31 31 <% else %>
32 32  
33 33 <h2><%= _("Enable e-Mail account below:") %></h2>
34   - <ul><%= profile.email_addresses.map{|i| content_tag('li', i)}.join("\n") %></ul>
  34 + <ul><%= safe_join(profile.email_addresses.map{|i| content_tag('li', i)}, "\n") %></ul>
35 35 <blockquote><%= _("You'll be able to access a webmail from your user menu.") %></blockquote>
36 36 <% button_bar do %>
37 37 <%= button(:ok, _('Enable e-Mail'), { :action => 'enable' }, :method => 'post') %>
... ...
app/views/manage_products/show.html.erb
... ... @@ -14,7 +14,7 @@
14 14 </div>
15 15 <div id='product-extra-content'>
16 16 <% extra_content = @plugins.dispatch(:product_info_extras, @product).collect { |content| instance_exec(&content) } %>
17   - <%= extra_content.join("\n") %>
  17 + <%= safe_join(extra_content, "\n") %>
18 18 </div>
19 19 <div id='product-info'>
20 20 <%= render :partial => 'manage_products/display_info' %>
... ...
app/views/pending_task_notifier/notification.text.erb
... ... @@ -2,7 +2,7 @@
2 2  
3 3 <%= _("You have %d pending task(s).") % @tasks.size %>
4 4  
5   -<%= @tasks.map{|i| " * #{i.description}"}.join("\n") %>
  5 +<%= safe_join(@tasks.map{|i| " * #{i.description}"}, "\n") %>
6 6  
7 7 <%= _("Click in address below to process task(s):") %>
8 8  
... ... @@ -11,7 +11,7 @@
11 11 <% pending_tasks = @person.pending_tasks_for_organization(organization) %>
12 12 <%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %>
13 13  
14   -<%= pending_tasks.map{|i| " * #{i.information}"}.join("\n") %>
  14 +<%= safe_join(pending_tasks.map{|i| " * #{i.information}"}, "\n") %>
15 15  
16 16 <%= _("Click in address below to process task(s):") %>
17 17  
... ...
app/views/profile/content_tagged.html.erb
... ... @@ -20,6 +20,6 @@
20 20 <%= pagination_links @tagged, :param_name => 'npage' %>
21 21  
22 22 <div>
23   - <%= link_to _('See content tagged with "%s" in the entire site') % escaped_tag, :controller => 'search', :action => 'tag', :tag => @tag %>
  23 + <%= link_to (_('See content tagged with "%s" in the entire site') % escaped_tag).html_safe, :controller => 'search', :action => 'tag', :tag => @tag %>
24 24 </div>
25 25 <% end %>
... ...
app/views/profile_editor/_organization.html.erb
... ... @@ -4,7 +4,7 @@
4 4  
5 5 <%= required f.text_field(:name) %>
6 6  
7   - <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }.join("") %>
  7 + <%= safe_join(@plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }, "") %>
8 8  
9 9 <% if @environment.enabled?('enable_organization_url_change') %>
10 10 <script type="text/javascript">
... ...
app/views/profile_editor/_person.html.erb
... ... @@ -16,7 +16,7 @@
16 16 </div>
17 17 </div>
18 18  
19   - <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }.join("") %>
  19 + <%= safe_join(@plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }, "") %>
20 20  
21 21 <div class="formfieldline">
22 22 <%= label_tag("private_token", _("Private Token")) %>
... ...
app/views/profile_editor/edit.html.erb
... ... @@ -60,9 +60,9 @@
60 60 )%>
61 61  
62 62 <%=
63   - @plugins.dispatch(:profile_editor_extras).map do |content|
  63 + safe_join(@plugins.dispatch(:profile_editor_extras).map do |content|
64 64 content.kind_of?(Proc) ? self.instance_exec(&content) : content
65   - end.join("\n")
  65 + end, "\n")
66 66 %>
67 67  
68 68 <%= select_categories(:profile_data, _('Select the categories of your interest'), 2) %>
... ...
app/views/search/_full_product.html.erb
1 1 <% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_exec(&content) } %>
2   -<% extra_properties = @plugins.dispatch(:asset_product_properties, product)%>
  2 +<% extra_properties = @plugins.dispatch(:asset_product_properties, product) %>
3 3  
4 4 <li class="search-product-item <%= 'highlighted' if product.highlighted? %>">
5 5  
... ... @@ -77,9 +77,9 @@
77 77  
78 78 <div style="clear: both"></div>
79 79  
80   - <%= extra_content.join('\n') %>
  80 + <%= safe_join(extra_content, '\n') %>
81 81 <% extra_properties.each do |property| %>
82   - <div><%= property[:name] + ': ' + instance_exec(&property[:content]) %></div>
  82 + <div><%= ''.html_safe + property[:name] + ': ' + instance_exec(&property[:content]) %></div>
83 83 <% end %>
84 84  
85 85 </li>
... ...
lib/noosfero/plugin.rb
... ... @@ -611,7 +611,7 @@ class Noosfero::Plugin
611 611 end
612 612  
613 613 # -> Perform extra transactions related to profile in profile editor
614   - # returns = true in success or raise and exception if it could not update the data
  614 + # returns = true in success or raise an exception if it could not update the data
615 615 def profile_editor_transaction_extras
616 616 nil
617 617 end
... ...
plugins/breadcrumbs/lib/breadcrumbs_plugin/content_breadcrumbs_block.rb
... ... @@ -49,7 +49,7 @@ class BreadcrumbsPlugin::ContentBreadcrumbsBlock &lt; Block
49 49  
50 50 def content(args={})
51 51 block = self
52   - proc do
  52 + ret = (proc do
53 53 trail = block.trail(@page, @profile, params)
54 54 if !trail.empty?
55 55 separator = content_tag('span', ' > ', :class => 'separator')
... ... @@ -67,7 +67,8 @@ class BreadcrumbsPlugin::ContentBreadcrumbsBlock &lt; Block
67 67 else
68 68 ''
69 69 end
70   - end
  70 + end)
  71 + ret.html_safe
71 72 end
72 73  
73 74 def cacheable?
... ...
plugins/community_block/lib/community_block.rb
... ... @@ -10,7 +10,6 @@ class CommunityBlock &lt; Block
10 10  
11 11 def content(arg={})
12 12 block = self
13   -
14 13 proc do
15 14 render :file => 'community_block', :locals => { :block => block }
16 15 end
... ...
plugins/context_content/lib/context_content_plugin/context_content_block.rb
... ... @@ -86,7 +86,7 @@ class ContextContentPlugin::ContextContentBlock &lt; Block
86 86  
87 87 def content(args={})
88 88 block = self
89   - proc do
  89 + ret = proc do
90 90 contents = block.contents(@page)
91 91 parent_title = block.parent_title(contents)
92 92 if !contents.blank?
... ... @@ -95,6 +95,7 @@ class ContextContentPlugin::ContextContentBlock &lt; Block
95 95 ''
96 96 end
97 97 end
  98 + ret.html_safe
98 99 end
99 100  
100 101 def cacheable?
... ...
plugins/display_content/lib/display_content_block.rb
... ... @@ -131,7 +131,7 @@ class DisplayContentBlock &lt; Block
131 131 docs = owner.articles.order(order_string).where(["articles.type IN(:types) #{nodes.blank? ? '' : nodes_conditions}", {:nodes => self.nodes, :types => self.types}]).includes(:profile, :image, :tags)
132 132 docs = docs.limit(limit_final) if display_folder_children
133 133  
134   - proc do
  134 + ret = (proc do
135 135 block.block_title(block.title) +
136 136 content_tag('ul', docs.map {|item|
137 137 if !item.folder? && item.class != RssFeed
... ... @@ -170,7 +170,8 @@ class DisplayContentBlock &lt; Block
170 170 content_tag('li', content_sections)
171 171 end
172 172 }.join(" "))
173   - end
  173 + end)
  174 + ret.html_safe
174 175 end
175 176  
176 177 def url_params
... ...
plugins/event/views/event_plugin/event_block_item.html.erb
... ... @@ -16,7 +16,7 @@
16 16 img_class = img.blank? ? 'no-img' : 'has-img'
17 17 %>
18 18 <%=
19   - link_to([
  19 + link_to(safe_join([
20 20 content_tag('time',
21 21 block.date_to_html(event.start_date),
22 22 :itemprop => 'startDate',
... ... @@ -33,7 +33,7 @@
33 33 :itemtype => 'http://schema.org/Place',
34 34 :itemprop => :location),
35 35 content_tag('span', time_left_str, :class => 'days-left ' + time_class)
36   - ].join("\n"),
  36 + ], "\n"),
37 37 (event.link.blank? ? event.url : event.link),
38 38 :class => 'ev-days-' + event.duration.to_s,
39 39 :itemprop => :url
... ...
plugins/people_block/lib/people_block_base.rb
... ... @@ -81,7 +81,7 @@ class PeopleBlockBase &lt; Block
81 81 end
82 82 list = content_tag 'ul', list
83 83 end
84   - block_title(title) + content_tag('div', list + tag('br', :style => 'clear:both'))
  84 + (block_title(title) + content_tag('div', list + tag('br', :style => 'clear:both'))).html_safe
85 85 end
86 86 end
87 87  
... ...
plugins/profile_members_headlines/views/blocks/headlines.html.erb
... ... @@ -15,7 +15,7 @@
15 15 <%= show_date(headline.published_at) %>
16 16 </div>
17 17 <div class='tags'>
18   - <%= headline.tags.map { |t| link_to(t, :controller => 'profile', :profile => member.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
  18 + <%= safe_join(headline.tags.map { |t| link_to(t, :controller => 'profile', :profile => member.identifier, :action => 'tags', :id => t.name ) }, "\n") %>
19 19 </div>
20 20 </div>
21 21 </div>
... ...
plugins/relevant_content/lib/relevant_content_plugin/relevant_content_block.rb
... ... @@ -83,7 +83,7 @@ class RelevantContentPlugin::RelevantContentBlock &lt; Block
83 83 end
84 84 end
85 85 end
86   - return content
  86 + return content.html_safe
87 87 end
88 88  
89 89 def timeout
... ...
public/designs/themes/base/footer.html.erb
... ... @@ -3,7 +3,7 @@
3 3 <%= link_to _('Manual'), '/doc', id: "link-to-doc", class: 'icon-help' %>
4 4 </div><!-- end id="footer-links" -->
5 5 <div id="copyright">
6   - <p><%= _('This social network uses <a href="http://noosfero.org/">Noosfero</a>, developed by %s and licensed under the <a href="http://www.gnu.org/licenses/agpl.html">GNU Affero General Public License</a> version 3 or any later version.') % link_to('Colivre', 'http://colivre.coop.br/') %></p>
  6 + <p><%= (_('This social network uses <a href="http://noosfero.org/">Noosfero</a>, developed by %s and licensed under the <a href="http://www.gnu.org/licenses/agpl.html">GNU Affero General Public License</a> version 3 or any later version.') % link_to('Colivre', 'http://colivre.coop.br/')).html_safe %></p>
7 7 </div><!-- end id="copyright" -->
8 8 <%= language_chooser(environment) %>
9 9 </div>
... ...
test/functional/account_controller_test.rb
... ... @@ -689,7 +689,7 @@ class AccountControllerTest &lt; ActionController::TestCase
689 689 should 'merge user data with extra stuff from plugins' do
690 690 class Plugin1 < Noosfero::Plugin
691 691 def user_data_extras
692   - {:foo => 'bar'}
  692 + {:foo => 'bar'.html_safe }
693 693 end
694 694 end
695 695  
... ... @@ -787,12 +787,12 @@ class AccountControllerTest &lt; ActionController::TestCase
787 787 should 'add extra content on signup forms from plugins' do
788 788 class Plugin1 < Noosfero::Plugin
789 789 def signup_extra_contents
790   - proc {"<strong>Plugin1 text</strong>"}
  790 + proc {"<strong>Plugin1 text</strong>".html_safe}
791 791 end
792 792 end
793 793 class Plugin2 < Noosfero::Plugin
794 794 def signup_extra_contents
795   - proc {"<strong>Plugin2 text</strong>"}
  795 + proc {"<strong>Plugin2 text</strong>".html_safe}
796 796 end
797 797 end
798 798 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ... @@ -909,12 +909,12 @@ class AccountControllerTest &lt; ActionController::TestCase
909 909 should 'add extra content on login form from plugins' do
910 910 class Plugin1 < Noosfero::Plugin
911 911 def login_extra_contents
912   - proc {"<strong>Plugin1 text</strong>"}
  912 + proc {"<strong>Plugin1 text</strong>".html_safe}
913 913 end
914 914 end
915 915 class Plugin2 < Noosfero::Plugin
916 916 def login_extra_contents
917   - proc {"<strong>Plugin2 text</strong>"}
  917 + proc {"<strong>Plugin2 text</strong>".html_safe}
918 918 end
919 919 end
920 920 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ...
test/functional/application_controller_test.rb
... ... @@ -375,7 +375,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
375 375 should 'include javascripts supplied by plugins' do
376 376 class Plugin1 < Noosfero::Plugin
377 377 def js_files
378   - ['js1.js']
  378 + ['js1.js'.html_safe]
379 379 end
380 380 end
381 381  
... ... @@ -384,7 +384,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
384 384  
385 385 class Plugin2 < Noosfero::Plugin
386 386 def js_files
387   - ['js2.js', 'js3.js']
  387 + ['js2.js'.html_safe, 'js3.js'.html_safe]
388 388 end
389 389 end
390 390  
... ... @@ -409,12 +409,12 @@ class ApplicationControllerTest &lt; ActionController::TestCase
409 409 should 'include content in the beginning of body supplied by plugins regardless it is a block or html code' do
410 410 class TestBodyBeginning1Plugin < Noosfero::Plugin
411 411 def body_beginning
412   - lambda {"<span id='plugin1'>This is [[plugin1]] speaking!</span>"}
  412 + lambda {"<span id='plugin1'>This is [[plugin1]] speaking!</span>".html_safe}
413 413 end
414 414 end
415 415 class TestBodyBeginning2Plugin < Noosfero::Plugin
416 416 def body_beginning
417   - "<span id='plugin2'>This is Plugin2 speaking!</span>"
  417 + "<span id='plugin2'>This is Plugin2 speaking!</span>".html_safe
418 418 end
419 419 end
420 420  
... ... @@ -432,12 +432,12 @@ class ApplicationControllerTest &lt; ActionController::TestCase
432 432  
433 433 class TestHeadEnding1Plugin < Noosfero::Plugin
434 434 def head_ending
435   - lambda {"<script>alert('This is [[plugin1]] speaking!')</script>"}
  435 + lambda {"<script>alert('This is [[plugin1]] speaking!')</script>".html_safe}
436 436 end
437 437 end
438 438 class TestHeadEnding2Plugin < Noosfero::Plugin
439 439 def head_ending
440   - "<style>This is Plugin2 speaking!</style>"
  440 + "<style>This is Plugin2 speaking!</style>".html_safe
441 441 end
442 442 end
443 443  
... ...
test/functional/catalog_controller_test.rb
... ... @@ -71,13 +71,13 @@ class CatalogControllerTest &lt; ActionController::TestCase
71 71 should 'include extra content supplied by plugins on catalog item extras' do
72 72 class Plugin1 < Noosfero::Plugin
73 73 def catalog_item_extras(product)
74   - proc {"<span id='plugin1'>This is Plugin1 speaking!</span>"}
  74 + proc {"<span id='plugin1'>This is Plugin1 speaking!</span>".html_safe}
75 75 end
76 76 end
77 77  
78 78 class Plugin2 < Noosfero::Plugin
79 79 def catalog_item_extras(product)
80   - proc {"<span id='plugin2'>This is Plugin2 speaking!</span>"}
  80 + proc {"<span id='plugin2'>This is Plugin2 speaking!</span>".html_safe}
81 81 end
82 82 end
83 83 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ...
test/functional/enterprise_registration_controller_test.rb
... ... @@ -191,13 +191,13 @@ class EnterpriseRegistrationControllerTest &lt; ActionController::TestCase
191 191 should 'include hidden fields supplied by plugins on enterprise registration' do
192 192 class Plugin1 < Noosfero::Plugin
193 193 def enterprise_registration_hidden_fields
194   - {'plugin1' => 'Plugin 1'}
  194 + {'plugin1' => 'Plugin 1'.html_safe}
195 195 end
196 196 end
197 197  
198 198 class Plugin2 < Noosfero::Plugin
199 199 def enterprise_registration_hidden_fields
200   - {'plugin2' => 'Plugin 2'}
  200 + {'plugin2' => 'Plugin 2'.html_safe}
201 201 end
202 202 end
203 203 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ...
test/functional/events_controller_test.rb
... ... @@ -13,7 +13,7 @@ class EventsControllerTest &lt; ActionController::TestCase
13 13  
14 14 get :events, :profile => profile.identifier
15 15  
16   - today = DateTime.now.strftime("%B %d, %Y")
  16 + today = DateTime.now.strftime("%B %d, %Y").html_safe
17 17 assert_tag :tag => 'div', :attributes => {:id => "agenda-items"},
18 18 :descendant => {:tag => 'h3', :content => "Events for #{today}"},
19 19 :descendant => {:tag => 'tr', :content => "Joao Birthday"},
... ...
test/functional/friends_controller_test.rb
... ... @@ -43,7 +43,7 @@ class FriendsControllerTest &lt; ActionController::TestCase
43 43  
44 44 should 'display find people button' do
45 45 get :index, :profile => 'testuser'
46   - assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/search/assets?asset=people' }
  46 + assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/search/assets?asset=people'.html_safe }
47 47 end
48 48  
49 49 should 'not display invite friends button if any plugin tells not to' do
... ...
test/functional/home_controller_test.rb
... ... @@ -88,12 +88,12 @@ class HomeControllerTest &lt; ActionController::TestCase
88 88 should 'provide a link to make the user authentication' do
89 89 class Plugin1 < Noosfero::Plugin
90 90 def alternative_authentication_link
91   - proc {"<a href='plugin1'>Plugin1 link</a>"}
  91 + proc {"<a href='plugin1'>Plugin1 link</a>".html_safe}
92 92 end
93 93 end
94 94 class Plugin2 < Noosfero::Plugin
95 95 def alternative_authentication_link
96   - proc {"<a href='plugin2'>Plugin2 link</a>"}
  96 + proc {"<a href='plugin2'>Plugin2 link</a>".html_safe}
97 97 end
98 98 end
99 99 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
... ... @@ -168,7 +168,7 @@ class HomeControllerTest &lt; ActionController::TestCase
168 168 should 'plugins add class to the <html>' do
169 169 class Plugin1 < Noosfero::Plugin
170 170 def html_tag_classes
171   - lambda { ['t1', 't2'] }
  171 + lambda { ['t1'.html_safe, 't2'.html_safe] }
172 172 end
173 173 end
174 174  
... ...
test/functional/manage_products_controller_test.rb
... ... @@ -429,12 +429,12 @@ class ManageProductsControllerTest &lt; ActionController::TestCase
429 429 should 'include extra content supplied by plugins on products info extras' do
430 430 class TestProductInfoExtras1Plugin < Noosfero::Plugin
431 431 def product_info_extras(p)
432   - proc {"<span id='plugin1'>This is Plugin1 speaking!</span>"}
  432 + proc {"<span id='plugin1'>This is Plugin1 speaking!</span>".html_safe}
433 433 end
434 434 end
435 435 class TestProductInfoExtras2Plugin < Noosfero::Plugin
436 436 def product_info_extras(p)
437   - proc { "<span id='plugin2'>This is Plugin2 speaking!</span>" }
  437 + proc { "<span id='plugin2'>This is Plugin2 speaking!</span>".html_safe }
438 438 end
439 439 end
440 440  
... ...
test/functional/profile_controller_test.rb
... ... @@ -125,7 +125,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
125 125 @profile.articles.create!(:name => 'testarticle', :tag_list => 'tag1')
126 126 get :content_tagged, :profile => @profile.identifier, :id => 'tag1'
127 127  
128   - assert_tag :tag => 'a', :attributes => { :href => '/tag/tag1' }, :content => 'See content tagged with "tag1" in the entire site'
  128 + assert_tag :tag => 'a', :attributes => { :href => '/tag/tag1' }, :content => 'See content tagged with "tag1" in the entire site'.html_safe
129 129 end
130 130  
131 131 should 'show a link to own control panel' do
... ... @@ -1236,13 +1236,13 @@ class ProfileControllerTest &lt; ActionController::TestCase
1236 1236 should 'display plugins tabs' do
1237 1237 class Plugin1 < Noosfero::Plugin
1238 1238 def profile_tabs
1239   - {:title => 'Plugin1 tab', :id => 'plugin1_tab', :content => proc { 'Content from plugin1.' }}
  1239 + {:title => 'Plugin1 tab', :id => 'plugin1_tab', :content => proc { 'Content from plugin1.'.html_safe }}
1240 1240 end
1241 1241 end
1242 1242  
1243 1243 class Plugin2 < Noosfero::Plugin
1244 1244 def profile_tabs
1245   - {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => proc { 'Content from plugin2.' }}
  1245 + {:title => 'Plugin2 tab', :id => 'plugin2_tab', :content => proc { 'Content from plugin2.'.html_safe }}
1246 1246 end
1247 1247 end
1248 1248 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -991,7 +991,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
991 991 should 'add extra content provided by plugins on edit' do
992 992 class TestProfileEditPlugin < Noosfero::Plugin
993 993 def profile_editor_extras
994   - "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>"
  994 + "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>".html_safe
995 995 end
996 996 end
997 997 Noosfero::Plugin.stubs(:all).returns([TestProfileEditPlugin.to_s])
... ... @@ -1007,7 +1007,7 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
1007 1007 class TestProfileEditPlugin < Noosfero::Plugin
1008 1008 def profile_editor_extras
1009 1009 lambda do
1010   - render :text => "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>"
  1010 + (render :text => "<input id='field_added_by_plugin' value='value_of_field_added_by_plugin'/>".html_safe).html_safe
1011 1011 end
1012 1012 end
1013 1013 end
... ... @@ -1032,12 +1032,12 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
1032 1032 should 'add extra content on person info from plugins' do
1033 1033 class Plugin1 < Noosfero::Plugin
1034 1034 def profile_info_extra_contents
1035   - proc {"<strong>Plugin1 text</strong>"}
  1035 + proc {"<strong>Plugin1 text</strong>".html_safe}
1036 1036 end
1037 1037 end
1038 1038 class Plugin2 < Noosfero::Plugin
1039 1039 def profile_info_extra_contents
1040   - proc {"<strong>Plugin2 text</strong>"}
  1040 + proc {"<strong>Plugin2 text</strong>".html_safe}
1041 1041 end
1042 1042 end
1043 1043 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
... ... @@ -1054,12 +1054,12 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
1054 1054 should 'add extra content on organization info from plugins' do
1055 1055 class Plugin1 < Noosfero::Plugin
1056 1056 def profile_info_extra_contents
1057   - proc {"<strong>Plugin1 text</strong>"}
  1057 + proc {"<strong>Plugin1 text</strong>".html_safe}
1058 1058 end
1059 1059 end
1060 1060 class Plugin2 < Noosfero::Plugin
1061 1061 def profile_info_extra_contents
1062   - proc {"<strong>Plugin2 text</strong>"}
  1062 + proc {"<strong>Plugin2 text</strong>".html_safe}
1063 1063 end
1064 1064 end
1065 1065 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
... ...
test/functional/search_controller_test.rb
... ... @@ -149,13 +149,13 @@ class SearchControllerTest &lt; ActionController::TestCase
149 149 should 'include extra content supplied by plugins on product asset' do
150 150 class Plugin1 < Noosfero::Plugin
151 151 def asset_product_extras(product)
152   - proc {"<span id='plugin1'>This is Plugin1 speaking!</span>"}
  152 + proc {"<span id='plugin1'>This is Plugin1 speaking!</span>".html_safe}
153 153 end
154 154 end
155 155  
156 156 class Plugin2 < Noosfero::Plugin
157 157 def asset_product_extras(product)
158   - proc {"<span id='plugin2'>This is Plugin2 speaking!</span>"}
  158 + proc {"<span id='plugin2'>This is Plugin2 speaking!</span>".html_safe}
159 159 end
160 160 end
161 161 Noosfero::Plugin.stubs(:all).returns([Plugin1.to_s, Plugin2.to_s])
... ...
test/mocks/test/test_controller.rb
... ... @@ -22,7 +22,7 @@ class TestController &lt; ApplicationController
22 22 end
23 23  
24 24 def help_textile_with_string
25   - render :inline => '<%= help_textile "*my_bold_help_message*" %>'
  25 + render :inline => '<%= help_textile "*my_bold_help_message*".html_safe %>'
26 26 end
27 27  
28 28 def help_textile_with_block
... ...
test/unit/plugin_manager_test.rb
... ... @@ -43,13 +43,13 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
43 43  
44 44 class Plugin1 < Noosfero::Plugin
45 45 def random_event
46   - 'Plugin 1 action.'
  46 + 'Plugin 1 action.'.html_safe
47 47 end
48 48 end
49 49  
50 50 class Plugin2 < Noosfero::Plugin
51 51 def random_event
52   - 'Plugin 2 action.'
  52 + 'Plugin 2 action.'.html_safe
53 53 end
54 54 end
55 55 Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
... ... @@ -70,19 +70,19 @@ class PluginManagerTest &lt; ActiveSupport::TestCase
70 70  
71 71 class Plugin1 < Noosfero::Plugin
72 72 def random_event
73   - 'Plugin 1 action.'
  73 + 'Plugin 1 action.'.html_safe
74 74 end
75 75 end
76 76  
77 77 class Plugin2 < Noosfero::Plugin
78 78 def random_event
79   - 'Plugin 2 action.'
  79 + 'Plugin 2 action.'.html_safe
80 80 end
81 81 end
82 82  
83 83 class Plugin3 < Noosfero::Plugin
84 84 def random_event
85   - 'Plugin 3 action.'
  85 + 'Plugin 3 action.'.html_safe
86 86 end
87 87 end
88 88 Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2', 'PluginManagerTest::Plugin3'])
... ...