Commit dab589514d270bc3e01ca1dc19e46f7d3cbe34d0

Authored by Carlos Purificação
Committed by Alexandre Barbosa
1 parent 27f11bf7

Fixing html_safe for noosfero core

Signed-off-by: Alexandre Barbosa <alexandreab@live.com>
Signed-off-by: Arthur Jahn <stutrzbecher@gmail.com>
Signed-off-by: David Carlos <ddavidcarlos1392@gmail.com>
Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com>
Signed-off-by: Victor Costa <vfcosta@gmail.com>
Showing 106 changed files with 327 additions and 277 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 106 files displayed.

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
... ... @@ -365,7 +365,7 @@ class CmsController &lt; MyProfileController
365 365 def search
366 366 query = params[:q]
367 367 results = find_by_contents(:uploaded_files, profile, profile.files.published, query)[:results]
368   - render :text => article_list_to_json(results), :content_type => 'application/json'
  368 + render :text => article_list_to_json(results).html_safe, :content_type => 'application/json'
369 369 end
370 370  
371 371 def search_article_privacy_exceptions
... ...
app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -29,6 +29,7 @@ class ProfileEditorController &lt; MyProfileController
29 29 Image.transaction do
30 30 begin
31 31 @plugins.dispatch(:profile_editor_transaction_extras)
  32 + # TODO: This is unsafe! Add sanitizer
32 33 @profile_data.update!(params[:profile_data])
33 34 redirect_to :action => 'index', :profile => profile.identifier
34 35 rescue Exception => ex
... ...
app/helpers/action_tracker_helper.rb
... ... @@ -15,12 +15,12 @@ module ActionTrackerHelper
15 15 end
16 16  
17 17 def join_community_description ta
18   - n_('has joined 1 community:<br />%{name}', 'has joined %{num} communities:<br />%{name}', ta.get_resource_name.size) % {
  18 + n_('has joined 1 community:<br />%{name}'.html_safe, 'has joined %{num} communities:<br />%{name}'.html_safe, ta.get_resource_name.size) % {
19 19 num: ta.get_resource_name.size,
20 20 name: ta.collect_group_with_index(:resource_name) do |n,i|
21   - link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")),
  21 + link = link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")),
22 22 ta.get_resource_url[i], title: n
23   - end.join
  23 + end.join.html_safe
24 24 }
25 25 end
26 26  
... ...
app/helpers/application_helper.rb
... ... @@ -99,7 +99,6 @@ module ApplicationHelper
99 99 #
100 100 # TODO: implement correcly the 'Help' button click
101 101 def help(content = nil, link_name = nil, options = {}, &block)
102   -
103 102 link_name ||= _('Help')
104 103  
105 104 @help_message_id ||= 1
... ... @@ -122,7 +121,7 @@ module ApplicationHelper
122 121 button = link_to_function(content_tag('span', link_name), "Element.show('#{help_id}')", options )
123 122 close_button = content_tag("div", link_to_function(_("Close"), "Element.hide('#{help_id}')", :class => 'close_help_button'))
124 123  
125   - 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')
  124 + 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')
126 125  
127 126 unless block.nil?
128 127 concat(text)
... ... @@ -362,8 +361,8 @@ module ApplicationHelper
362 361 def popover_menu(title,menu_title,links,html_options={})
363 362 html_options[:class] = "" unless html_options[:class]
364 363 html_options[:class] << " menu-submenu-trigger"
365   - html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false"
366 364  
  365 + html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false".html_safe
367 366 link_to(content_tag(:span, title), '#', html_options)
368 367 end
369 368  
... ... @@ -473,9 +472,9 @@ module ApplicationHelper
473 472 map(&:role)
474 473 names = []
475 474 roles.each do |role|
476   - names << content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}")
  475 + names << content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}").html_safe
477 476 end
478   - names.join(', ')
  477 + safe_join(names, ', ')
479 478 end
480 479  
481 480 def role_color(role, env_id)
... ... @@ -911,7 +910,8 @@ module ApplicationHelper
911 910 end
912 911  
913 912 def admin_link
914   - 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') : ''
  913 + admin_icon = '<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>'
  914 + user.is_admin?(environment) ? link_to(admin_icon.html_safe, environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : ''
915 915 end
916 916  
917 917 def usermenu_logged_in
... ... @@ -920,23 +920,39 @@ module ApplicationHelper
920 920 if count > 0
921 921 pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks"))
922 922 end
  923 + user_identifier = "<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>"
  924 + welcome_link = link_to(user_identifier.html_safe, user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage'))
  925 + welcome_span = _("<span class='welcome'>Welcome,</span> %s") % welcome_link.html_safe
  926 + ctrl_panel_icon = '<i class="icon-menu-ctrl-panel"></i>'
  927 + ctrl_panel_section = '<strong>' + ctrl_panel_icon + _('Control panel') + '</strong>'
  928 + ctrl_panel_link = link_to(ctrl_panel_section.html_safe, user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content"))
  929 + logout_icon = '<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>'
  930 + logout_link = link_to(logout_icon.html_safe, { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system"))
  931 + join_result = safe_join(
  932 + [welcome_span.html_safe, render_environment_features(:usermenu).html_safe, admin_link.html_safe,
  933 + manage_enterprises.html_safe, manage_communities.html_safe, ctrl_panel_link.html_safe,
  934 + pending_tasks_count.html_safe, logout_link.html_safe], "")
  935 + join_result
  936 + end
923 937  
924   - (_("<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'))) +
925   - render_environment_features(:usermenu) +
926   - admin_link +
927   - manage_enterprises +
928   - manage_communities +
929   - 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")) +
930   - pending_tasks_count +
931   - link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system"))
  938 + def usermenu_notlogged_in
  939 + login_str = '<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>'
  940 + ret = _("<span class='login'>%s</span>") % modal_inline_link_to(login_str.html_safe, login_url, '#inlineLoginBox', :id => 'link_login')
  941 + return ret.html_safe
932 942 end
933 943  
  944 + def usermenu_signup
  945 + signup_str = '<strong>' + _('Sign up') + '</strong>'
  946 + ret = _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to(signup_str.html_safe, :controller => 'account', :action => 'signup')
  947 + return ret.html_safe
  948 +
  949 + end
934 950 def limited_text_area(object_name, method, limit, text_area_id, options = {})
935   - content_tag(:div, [
  951 + content_tag(:div, safe_join([
936 952 text_area(object_name, method, { :id => text_area_id, :onkeyup => "limited_text_area('#{text_area_id}', #{limit})" }.merge(options)),
937 953 content_tag(:p, content_tag(:span, limit) + ' ' + _(' characters left'), :id => text_area_id + '_left'),
938 954 content_tag(:p, _('Limit of characters reached'), :id => text_area_id + '_limit', :style => 'display: none')
939   - ].join, :class => 'limited-text-area')
  955 + ]), :class => 'limited-text-area')
940 956 end
941 957  
942 958 def expandable_text_area(object_name, method, text_area_id, options = {})
... ... @@ -1032,8 +1048,8 @@ module ApplicationHelper
1032 1048 end
1033 1049  
1034 1050 def render_tabs(tabs)
1035   - titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
1036   - contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
  1051 + titles = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
  1052 + contents = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
1037 1053  
1038 1054 content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs')
1039 1055 end
... ... @@ -1051,7 +1067,7 @@ module ApplicationHelper
1051 1067 def expirable_link_to(expired, content, url, options = {})
1052 1068 if expired
1053 1069 options[:class] = (options[:class] || '') + ' disabled'
1054   - content_tag('a', '&nbsp;'+content_tag('span', content), options)
  1070 + content_tag('a', '&nbsp;'.html_safe+content_tag('span', content), options)
1055 1071 else
1056 1072 if options[:modal]
1057 1073 options.delete(:modal)
... ... @@ -1084,7 +1100,7 @@ module ApplicationHelper
1084 1100  
1085 1101 radios = templates.map do |template|
1086 1102 content_tag('li', labelled_radio_button(link_to(template.name, template.url, :target => '_blank'), "#{field_name}[template_id]", template.id, environment.is_default_template?(template)))
1087   - end.join("\n")
  1103 + end.join("\n").html_safe
1088 1104  
1089 1105 content_tag('div', content_tag('label', _('Profile organization'), :for => 'template-options', :class => 'formlabel') +
1090 1106 content_tag('p', _('Your profile will be created according to the selected template. Click on the options to view them.'), :style => 'margin: 5px 15px;padding: 0px 10px;') +
... ... @@ -1124,7 +1140,7 @@ module ApplicationHelper
1124 1140 content_tag(:div, :class => 'errorExplanation', :id => 'errorExplanation') do
1125 1141 content_tag(:h2, _('Errors while saving')) +
1126 1142 content_tag(:ul) do
1127   - errors.map { |err| content_tag(:li, err) }.join
  1143 + safe_join(errors.map { |err| content_tag(:li, err) })
1128 1144 end
1129 1145 end
1130 1146 end
... ... @@ -1234,6 +1250,7 @@ module ApplicationHelper
1234 1250 :href=>"#",
1235 1251 :title=>_("Exit full screen mode")
1236 1252 })
  1253 + content.html_safe
1237 1254 end
1238 1255  
1239 1256 end
... ...
app/helpers/block_helper.rb
... ... @@ -3,13 +3,13 @@ module BlockHelper
3 3 def block_title(title, subtitle=nil)
4 4 block_header = block_heading title
5 5 block_header += block_heading(subtitle, 'h4') if subtitle
6   - content_tag 'div', block_header, :class => 'block-header'
  6 + content_tag('div', block_header, :class => 'block-header').html_safe
7 7 end
8 8  
9 9 def block_heading(title, heading='h3')
10 10 tag_class = 'block-' + (heading == 'h3' ? 'title' : 'subtitle')
11 11 tag_class += ' empty' if title.empty?
12   - content_tag heading, content_tag('span', h(title)), :class => tag_class
  12 + content_tag heading, content_tag('span', h(title)), :class => tag_class.html_safe
13 13 end
14 14  
15 15 def highlights_block_config_image_fields(block, image={}, row_number=nil)
... ...
app/helpers/blog_helper.rb
... ... @@ -41,12 +41,12 @@ module BlogHelper
41 41 css_add << position
42 42 content << (content_tag 'div', id: "post-#{art.id}", class: css_add do
43 43 content_tag 'div', class: position + '-inner blog-post-inner' do
44   - display_post(art, conf[:format]).html_safe +
45   - '<br style="clear:both"/>'.html_safe
  44 + display_post(art, conf[:format]) +
  45 + '<br style="clear:both"/>'
46 46 end
47   - end)
  47 + end).html_safe
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/box_organizer_helper.rb
... ... @@ -38,7 +38,7 @@ module BoxOrganizerHelper
38 38 content_tag(:ul,
39 39 images_path.map do |preview|
40 40 content_tag(:li, image_tag(preview, height: '240', alt: ''))
41   - end.join("\n")
  41 + end.join("\n").html_safe
42 42 )
43 43 end
44 44  
... ...
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
... ... @@ -136,17 +137,18 @@ module BoxesHelper
136 137  
137 138 result = filter_html(result, block)
138 139  
139   - content_tag('div',
140   - box_decorator.block_target(block.box, block) +
141   - content_tag('div',
142   - content_tag('div',
143   - content_tag('div',
144   - result + footer_content + box_decorator.block_edit_buttons(block),
145   - :class => 'block-inner-2'),
146   - :class => 'block-inner-1'),
147   - options),
148   - :class => 'block-outer') +
149   - box_decorator.block_handle(block)
  140 + join_result = safe_join([result, footer_content, box_decorator.block_edit_buttons(block)])
  141 + content_tag_inner_1 = content_tag('div', join_result, :class => 'block-inner-2')
  142 +
  143 + content_tag_inner_2 = content_tag('div', content_tag_inner_1, :class => 'block-inner-1')
  144 + content_tag_inner_3 = content_tag('div', content_tag_inner_2, options)
  145 + content_tag_inner_4 = box_decorator.block_target(block.box, block) + content_tag_inner_3
  146 + c = content_tag('div', content_tag_inner_4, :class => 'block-outer')
  147 + box_decorator_result = box_decorator.block_handle(block)
  148 + result_final = safe_join([c, box_decorator_result], "")
  149 +
  150 +
  151 + return result_final
150 152 end
151 153  
152 154 def wrap_main_content(content)
... ... @@ -156,17 +158,17 @@ module BoxesHelper
156 158 def extract_block_content(content)
157 159 case content
158 160 when Hash
159   - content_tag('iframe', '', :src => url_for(content))
  161 + content_tag('iframe', ''.html_safe, :src => url_for(content))
160 162 when String
161 163 if content.split("\n").size == 1 and content =~ /^https?:\/\//
162   - content_tag('iframe', '', :src => content)
  164 + content_tag('iframe', ''.html_safe, :src => content)
163 165 else
164 166 content
165 167 end
166 168 when Proc
167 169 self.instance_eval(&content)
168 170 when NilClass
169   - ''
  171 + ''.html_safe
170 172 else
171 173 raise "Unsupported content for block (#{content.class})"
172 174 end
... ... @@ -175,14 +177,14 @@ module BoxesHelper
175 177 module DontMoveBlocks
176 178 # does nothing
177 179 def self.block_target(box, block = nil)
178   - ''
  180 + ''.html_safe
179 181 end
180 182 # does nothing
181 183 def self.block_handle(block)
182   - ''
  184 + ''.html_safe
183 185 end
184 186 def self.block_edit_buttons(block)
185   - ''
  187 + ''.html_safe
186 188 end
187 189 def self.select_blocks box, arr, context
188 190 arr = arr.select{ |block| block.visible? context }
... ... @@ -229,9 +231,9 @@ module BoxesHelper
229 231 # makes the given block draggable so it can be moved away.
230 232 def block_handle(block)
231 233 return "" unless movable?(block)
232   - icon = "<div><div>#{display_icon(block.class)}</div><span>#{_(block.class.pretty_name)}</span></div>"
  234 + icon = "<div><div>#{display_icon(block.class)}</div><span>#{_(block.class.pretty_name)}</span></div>".html_safe
233 235 block_draggable("block-#{block.id}",
234   - :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}")
  236 + :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}".html_safe)
235 237 end
236 238  
237 239 def block_draggable(element_id, options={})
... ... @@ -302,7 +304,7 @@ module BoxesHelper
302 304 buttons << modal_inline_icon(:embed, _('Embed code'), {}, "#embed-code-box-#{block.id}") << html
303 305 end
304 306  
305   - content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar')
  307 + content_tag('div', buttons.join("\n").html_safe + tag('br', :style => 'clear: left'), :class => 'button-bar')
306 308 end
307 309  
308 310 def current_blocks
... ...
app/helpers/buttons_helper.rb
... ... @@ -15,9 +15,9 @@ module ButtonsHelper
15 15 end
16 16 the_title = html_options[:title] || label
17 17 if html_options[:disabled]
18   - content_tag('a', '&nbsp;'+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title))
  18 + content_tag('a', '&nbsp;'.html_safe+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title))
19 19 else
20   - link_to('&nbsp;'+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title))
  20 + link_to('&nbsp;'.html_safe+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title))
21 21 end
22 22 end
23 23  
... ...
app/helpers/catalog_helper.rb
... ... @@ -19,18 +19,18 @@ 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)
26 26 count = profile.products.from_category(category).count
27 27 name = truncate(category.name, :length => 22 - count.to_s.size)
28 28 link = link_to(name, {:controller => 'catalog', :action => 'index', :level => category.id}, :title => category.name)
29   - content_tag('div', "#{link} <span class=\"count\">#{count}</span>") if count > 0
  29 + content_tag('div', "#{link} <span class=\"count\">#{count}</span>".html_safe) if count > 0
30 30 end
31 31  
32 32 def category_with_sub_list(category)
33   - content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}"
  33 + content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}".html_safe
34 34 end
35 35  
36 36 def sub_category_list(category)
... ... @@ -39,7 +39,7 @@ module CatalogHelper
39 39 cat_link = category_link sub_category
40 40 sub_categories << content_tag('li', cat_link) unless cat_link.nil?
41 41 end
42   - content_tag('ul', sub_categories.join) if sub_categories.size > 0
  42 + content_tag('ul', sub_categories.join.html_safe) if sub_categories.size > 0
43 43 end
44 44  
45 45 end
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -7,7 +7,8 @@ module ContentViewerHelper
7 7 def display_number_of_comments(n)
8 8 base_str = "<span class='comment-count hide'>#{n}</span>"
9 9 amount_str = n == 0 ? _('no comments yet') : (n == 1 ? _('One comment') : _('%s comments') % n)
10   - base_str + "<span class='comment-count-write-out'>#{amount_str}</span>"
  10 + base_str += "<span class='comment-count-write-out'>#{amount_str}</span>"
  11 + base_str.html_safe
11 12 end
12 13  
13 14 def number_of_comments(article)
... ... @@ -19,11 +20,11 @@ module ContentViewerHelper
19 20 title = content_tag('h1', h(title), :class => 'title')
20 21 if article.belongs_to_blog? || article.belongs_to_forum?
21 22 unless args[:no_link]
22   - title = content_tag('h1', link_to(article.name, article.url), :class => 'title')
  23 + title = content_tag('h1', link_to(article.name, url_for(article.url)), :class => 'title')
23 24 end
24 25 comments = ''
25 26 unless args[:no_comments] || !article.accept_comments
26   - comments = (" - %s") % link_to_comments(article)
  27 + comments = (" - %s").html_safe % link_to_comments(article)
27 28 end
28 29 date_format = show_with_right_format_date article
29 30 title << content_tag('span',
... ...
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   - :rel => 'nofolow', :onclick => "return confirm('%s')" %
  66 + :rel => 'nofolow', :onclick => "return confirm('%s')".html_safe %
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
1 1 module EventsHelper
2 2  
3 3 include DatesHelper
  4 + include ActionView::Helpers::OutputSafetyHelper
  5 +
4 6 def list_events(date, events)
5 7 title = _('Events for %s') % show_date_month(date)
  8 + user_events = events.select { |item| item.display_to?(user) }
  9 + events_for_month = safe_join(user_events.map {|item| display_event_in_listing(item)}, '')
6 10 content_tag('h2', title) +
7 11 content_tag('div',
8 12 (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')
  13 + content_tag('table', events_for_month) :
  14 + content_tag('em', _('No events for this month'), :class => 'no-events')
11 15 ), :id => 'agenda-items'
12 16 )
13 17 end
... ...
app/helpers/forms_helper.rb
... ... @@ -101,7 +101,7 @@ module FormsHelper
101 101  
102 102 def required_fields_message
103 103 content_tag('p', content_tag('span',
104   - _("The <label class='pseudoformlabel'>highlighted</label> fields are mandatory."),
  104 + _("The <label class='pseudoformlabel'>highlighted</label> fields are mandatory.").html_safe,
105 105 :class => 'required-field'
106 106 ))
107 107 end
... ... @@ -112,10 +112,11 @@ module FormsHelper
112 112 options_for_select = container.inject([]) do |options, element|
113 113 text, value = option_text_and_value(element)
114 114 selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
115   - options << %(<option title="#{html_escape(text.to_s)}" value="#{html_escape(value.to_s)}"#{selected_attribute}>#{html_escape(text.to_s)}</option>)
  115 + opt = %(<option title="#{html_escape(text.to_s)}" value="#{html_escape(value.to_s)}"#{selected_attribute}>#{html_escape(text.to_s)}</option>)
  116 + options << opt.html_safe
116 117 end
117 118  
118   - options_for_select.join("\n")
  119 + safe_join(options_for_select, "\n")
119 120 end
120 121  
121 122 def balanced_table(items, per_row=3)
... ... @@ -248,8 +249,8 @@ module FormsHelper
248 249 def date_range_field(from_name, to_name, from_value, to_value, datepicker_options = {}, html_options = {})
249 250 from_id = html_options[:from_id] || 'datepicker-from-date'
250 251 to_id = html_options[:to_id] || 'datepicker-to-date'
251   - return _('From') +' '+ date_field(from_name, from_value, datepicker_options, html_options.merge({:id => from_id})) +
252   - ' ' + _('until') +' '+ date_field(to_name, to_value, datepicker_options, html_options.merge({:id => to_id}))
  252 + return (_('From') +' '+ date_field(from_name, from_value, datepicker_options, html_options.merge({:id => from_id})) +
  253 + ' ' + _('until') +' '+ date_field(to_name, to_value, datepicker_options, html_options.merge({:id => to_id}))).html_safe
253 254 end
254 255  
255 256 def select_folder(label_text, field_id, collection, default_value=nil, html_options = {}, js_options = {})
... ...
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/language_helper.rb
... ... @@ -40,7 +40,7 @@ module LanguageHelper
40 40 else
41 41 link_to(name, params.merge(:lang => code), :rel => 'nofollow')
42 42 end
43   - end.join(separator)
  43 + end.join(separator).html_safe
44 44 content_tag('div', languages, :id => 'language-chooser', :help => _('The language you choose here is the language used for options, buttons, etc. It does not affect the language of the content created by other users.'))
45 45 end
46 46 end
... ...
app/helpers/layout_helper.rb
... ... @@ -40,7 +40,8 @@ module LayoutHelper
40 40  
41 41 output += templete_javascript_ng.to_s
42 42  
43   - output
  43 + # This output should be safe!
  44 + output.html_safe
44 45 end
45 46  
46 47 def noosfero_stylesheets
... ... @@ -64,7 +65,9 @@ module LayoutHelper
64 65 output << stylesheet_link_tag(global_css_pub)
65 66 end
66 67 output << stylesheet_link_tag(theme_stylesheet_path)
67   - output.join "\n"
  68 +
  69 + # This output should be safe!
  70 + output.join("\n").html_safe
68 71 end
69 72  
70 73 def noosfero_layout_features
... ...
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/profile_image_helper.rb
... ... @@ -131,7 +131,7 @@ module ProfileImageHelper
131 131 links = links_for_balloon(profile)
132 132 content_tag('div', content_tag(tag,
133 133 (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ?
134   - popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "") +
  134 + popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "").html_safe +
135 135 link_to(
136 136 content_tag( 'span', profile_image( profile, size ), :class => img_class ) +
137 137 content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) +
... ... @@ -139,7 +139,7 @@ module ProfileImageHelper
139 139 profile.url,
140 140 :class => 'profile_link url',
141 141 :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name,
142   - :title => profile.name ),
  142 + :title => profile.name ).html_safe,
143 143 :class => 'vcard'), :class => 'common-profile-list-block')
144 144 end
145 145 end
... ...
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/helpers/tags_helper.rb
... ... @@ -58,7 +58,7 @@ module TagsHelper
58 58  
59 59 if options[:show_count]
60 60 display_count = options[:show_count] ? "<small><sup>(#{count})</sup></small>" : ""
61   - link_to tag + display_count, destination, :style => style
  61 + link_to (tag + display_count).html_safe, destination, :style => style
62 62 else
63 63 link_to h(tag) , destination, :style => style,
64 64 :title => n_( 'one item', '%d items', count ) % count
... ...
app/helpers/tinymce_helper.rb
... ... @@ -7,7 +7,7 @@ module TinymceHelper
7 7 output += javascript_include_tag 'tinymce/js/tinymce/jquery.tinymce.min.js'
8 8 output += javascript_include_tag 'tinymce.js'
9 9 output += include_macro_js_files.to_s
10   - output
  10 + output.html_safe
11 11 end
12 12  
13 13 def tinymce_init_js options = {}
... ... @@ -37,7 +37,7 @@ module TinymceHelper
37 37 #cleanup non tinymce options
38 38 options = options.except :mode
39 39  
40   - "noosfero.tinymce.init(#{options.to_json})"
  40 + "noosfero.tinymce.init(#{options.to_json})".html_safe
41 41 end
42 42  
43 43 def menubar mode
... ...
app/models/approve_article.rb
... ... @@ -86,7 +86,7 @@ class ApproveArticle &lt; Task
86 86  
87 87 def information
88 88 if article
89   - {:message => _('%{requestor} wants to publish the article: %{linked_subject}.')}
  89 + {:message => _('%{requestor} wants to publish the article: %{linked_subject}.').html_safe}
90 90 else
91 91 {:message => _("The article was removed.")}
92 92 end
... ...
app/models/create_community.rb
... ... @@ -60,9 +60,9 @@ class CreateCommunity &lt; Task
60 60  
61 61 def information
62 62 if description.blank?
63   - { :message => _('%{requestor} wants to create community %{subject} with no description.') }
  63 + { :message => _('%{requestor} wants to create community %{subject} with no description.').html_safe }
64 64 else
65   - { :message => _('%{requestor} wants to create community %{subject} with this description:<p><em>%{description}</em></p>'),
  65 + { :message => _('%{requestor} wants to create community %{subject} with this description:<p><em>%{description}</em></p>').html_safe,
66 66 :variables => {:description => description} }
67 67 end
68 68 end
... ...
app/models/create_enterprise.rb
... ... @@ -163,7 +163,7 @@ class CreateEnterprise &lt; Task
163 163 end
164 164  
165 165 def information
166   - {:message => _('%{requestor} wants to create enterprise %{subject}.')}
  166 + {:message => _('%{requestor} wants to create enterprise %{subject}.').html_safe}
167 167 end
168 168  
169 169 def reject_details
... ...
app/models/doc_item.rb
... ... @@ -17,7 +17,7 @@ class DocItem
17 17 else
18 18 match
19 19 end
20   - end
  20 + end.html_safe
21 21 end
22 22  
23 23 private
... ...
app/models/environment.rb
... ... @@ -729,7 +729,7 @@ class Environment &lt; ActiveRecord::Base
729 729 url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname)
730 730 url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port)
731 731 url << Noosfero.root('')
732   - url
  732 + url.html_safe
733 733 end
734 734  
735 735 def to_s
... ...
app/models/invite_friend.rb
... ... @@ -13,7 +13,7 @@ class InviteFriend &lt; Invitation
13 13 end
14 14  
15 15 def information
16   - {:message => _('%{requestor} wants to be your friend.')}
  16 + {:message => _('%{requestor} wants to be your friend.').html_safe}
17 17 end
18 18  
19 19 def accept_details
... ... @@ -25,7 +25,7 @@ class InviteFriend &lt; Invitation
25 25 end
26 26  
27 27 def target_notification_description
28   - _('%{requestor} wants to be your friend.') % {:requestor => requestor.name}
  28 + (_('%{requestor} wants to be your friend.') % {:requestor => requestor.name}).html_safe
29 29 end
30 30  
31 31 def permission
... ...
app/models/invite_member.rb
... ... @@ -25,7 +25,7 @@ class InviteMember &lt; Invitation
25 25 end
26 26  
27 27 def information
28   - {:message => _('%{requestor} invited you to join %{linked_subject}.')}
  28 + {:message => _('%{requestor} invited you to join %{linked_subject}.').html_safe}
29 29 end
30 30  
31 31 def url
... ... @@ -37,7 +37,7 @@ class InviteMember &lt; Invitation
37 37 end
38 38  
39 39 def target_notification_description
40   - _('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name}
  40 + (_('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name}).html_safe
41 41 end
42 42  
43 43 def target_notification_message
... ...
app/models/profile.rb
... ... @@ -646,7 +646,7 @@ class Profile &lt; ActiveRecord::Base
646 646 url << url_options[:host]
647 647 url << ':' << url_options[:port].to_s if url_options.key?(:port)
648 648 url << Noosfero.root('')
649   - url
  649 + url.html_safe
650 650 end
651 651  
652 652 private :generate_url, :url_options
... ...
app/models/suggest_article.rb
... ... @@ -65,7 +65,7 @@ class SuggestArticle &lt; Task
65 65  
66 66 def information
67 67 variables = requestor.blank? ? {:requestor => sender} : {}
68   - { :message => _('%{requestor} suggested the publication of the article: %{subject}.'),
  68 + { :message => _('%{requestor} suggested the publication of the article: %{subject}.').html_safe,
69 69 :variables => variables }
70 70 end
71 71  
... ... @@ -78,7 +78,7 @@ class SuggestArticle &lt; Task
78 78 end
79 79  
80 80 def target_notification_description
81   - _('%{requestor} suggested the publication of the article: %{article}.') %
  81 + _('%{requestor} suggested the publication of the article: %{article}.').html_safe %
82 82 {:requestor => sender, :article => article_name}
83 83 end
84 84  
... ...
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/activate_enterprise.html.erb
... ... @@ -14,7 +14,7 @@
14 14 <div id="enterprise-activation-create-user-form" style="display: none">
15 15 <h3><%= _('Personal signup form') %></h3>
16 16 <%= render :partial => 'signup_form', :locals => { :hidden_atention => true } %>
17   - <p><%= message = _('<b>Warning</b>: this form is for your personal information, not of your enterprise. So you will have a personal account that can manage your enterprise.') %></p>
  17 + <p><%= message = _('<b>Warning</b>: this form is for your personal information, not of your enterprise. So you will have a personal account that can manage your enterprise.').html_safe %></p>
18 18 </div>
19 19  
20 20 <div id="enterprise-activation-login-form" style="display: none">
... ...
app/views/account/invalid_change_password_code.html.erb
1 1 <h1><%= _("Invalid change password code") %></h1>
2 2  
3 3 <p>
4   -<%= _('The code you are using for password change is not valid. Please try to request password change using the <a href="%s">"I forgot my password"</a> functionality.') % url_for(:action => 'forgot_password') %>
  4 +<%= _('The code you are using for password change is not valid. Please try to request password change using the <a href="%s">"I forgot my password"</a> functionality.') % url_for(:action => 'forgot_password').html_safe %>
5 5 </p>
... ...
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/account/new_password_ok.html.erb
... ... @@ -5,5 +5,5 @@
5 5 </p>
6 6  
7 7 <p>
8   -<%= _("You can <a href='%s'>login</a> now.") % url_for(:action => 'login') %>
  8 +<%= _("You can <a href='%s'>login</a> now.").html_safe % url_for(:action => 'login') %>
9 9 </p>
... ...
app/views/blocks/blog_archives.html.erb
... ... @@ -6,7 +6,7 @@
6 6 <%= content_tag('li', content_tag('strong', "#{year.to_i} (#{count})")) %>
7 7 <ul class='<%= year.to_i %>-archive'>
8 8 <% block.blog.total_number_of_posts(:by_month, year).each do |month, count| %>
9   - <%= content_tag('li', link_to("#{month_name(month.to_i)} (#{count})", block.blog.url.merge(year: year.to_i, month: month.to_i))) %>
  9 + <%= content_tag('li', link_to("#{month_name(month.to_i)} (#{count})", url_for(block.blog.url.merge(year: year.to_i, month: month.to_i)).html_safe)) %>
10 10 <% end %>
11 11 </ul>
12 12 <% end %>
... ...
app/views/blocks/link_list.html.erb
... ... @@ -8,7 +8,7 @@
8 8 <%= block.sanitize_link(link_to(link[:name], block.expand_address(link[:address]),
9 9 :target => link[:target],
10 10 :class => (link[:icon] ? "icon-#{link[:icon]}" : ''),
11   - :title => link[:title])) %>
  11 + :title => link[:title])).html_safe %>
12 12 </li>
13 13 <% end %>
14 14 </ul>
... ...
app/views/blocks/login.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/blocks/profile_list.html.erb
... ... @@ -10,8 +10,8 @@
10 10 <% if list.empty? %>
11 11 <div class='common-profile-list-block-none'><%= _('None') %></div>
12 12 <% else %>
13   - <ul><%= list %></ul>
  13 + <ul><%= list.html_safe %></ul>
14 14 <% end %>
15 15 </div>
16   -
  16 +
17 17 <br style='clear:both'/>
... ...
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/_blog.html.erb
... ... @@ -35,7 +35,7 @@
35 35 <div id="article-formitem">
36 36 <%= labelled_form_field( _('Address'),
37 37 content_tag('code',
38   - url_for(@article.url).gsub(/#{@article.slug}$/, '') +
  38 + url_for(@article.url).gsub(/#{@article.slug}$/, '').html_safe +
39 39 text_field(:article, :slug, :onchange => "warn_value_change()", :size => 25)
40 40 ) +
41 41 content_tag('div',
... ...
app/views/cms/_textile_quick_reference.html.erb
... ... @@ -14,7 +14,7 @@
14 14 <p><%= _('Numbered lists:') %></p>
15 15 <pre># <%= _('first item') %>
16 16 # <%= _('second item') %></pre>
17   - <p><%= h(_('For code, use HTML tags <pre> and <code>, and indent the code inside them:')) %>
  17 + <p><%= h(_('For code, use HTML tags <pre> and <code>, and indent the code inside them:').html_safe) %>
18 18 </p>
19 19 <pre>
20 20 &lt;pre&gt;
... ... @@ -23,7 +23,7 @@
23 23 &lt;/code&gt;
24 24 &lt;/pre&gt;
25 25 </pre>
26   - <p><%= _('See also a more complete <a href="%s">Textile Reference</a>.') % 'http://redcloth.org/hobix.com/textile/' %></p>
  26 + <p><%= _('See also a more complete <a href="%s">Textile Reference</a>.').html_safe % 'http://redcloth.org/hobix.com/textile/' %></p>
27 27 </div>
28 28 </div>
29 29  
... ...
app/views/cms/edit.html.erb
... ... @@ -39,7 +39,7 @@
39 39  
40 40 <script>
41 41 jQuery('#article_tag_list').inputosaurus({
42   - autoCompleteSource: <%= "'/myprofile/#{profile.identifier}/cms/search_tags'," %>
  42 + autoCompleteSource: <%= "'/myprofile/#{profile.identifier}/cms/search_tags',".html_safe %>
43 43 activateFinalResult : true
44 44 })
45 45 </script>
... ...
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
... ... @@ -17,7 +17,7 @@
17 17 <% button_bar(:style => 'margin-bottom: 1em;') do %>
18 18 <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %>
19 19  
20   - <%= modal_button('new', _('New content'), :action => 'new', :parent_id => parent_id, :cms => true) %>
  20 + <%= modal_button('new', _('New content'), url_for({:action => 'new', :parent_id => parent_id, :cms => true}).html_safe) %>
21 21 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor', :action => "index") %>
22 22 <% end %>
23 23  
... ... @@ -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