diff --git a/app/controllers/my_profile/cms_controller.rb b/app/controllers/my_profile/cms_controller.rb index b218b11..4d5e070 100644 --- a/app/controllers/my_profile/cms_controller.rb +++ b/app/controllers/my_profile/cms_controller.rb @@ -108,7 +108,7 @@ class CmsController < MyProfileController end def new - # FIXME this method should share some logic wirh edit !!! + # FIXME this method should share some logic with edit !!! @success_back_to = params[:success_back_to] # user must choose an article type first @@ -365,7 +365,7 @@ class CmsController < MyProfileController def search query = params[:q] results = find_by_contents(:uploaded_files, profile, profile.files.published, query)[:results] - render :text => article_list_to_json(results), :content_type => 'application/json' + render :text => article_list_to_json(results).html_safe, :content_type => 'application/json' end def search_article_privacy_exceptions diff --git a/app/controllers/my_profile/profile_editor_controller.rb b/app/controllers/my_profile/profile_editor_controller.rb index 2680c0a..eb402fb 100644 --- a/app/controllers/my_profile/profile_editor_controller.rb +++ b/app/controllers/my_profile/profile_editor_controller.rb @@ -29,6 +29,7 @@ class ProfileEditorController < MyProfileController Image.transaction do begin @plugins.dispatch(:profile_editor_transaction_extras) + # TODO: This is unsafe! Add sanitizer @profile_data.update!(params[:profile_data]) redirect_to :action => 'index', :profile => profile.identifier rescue Exception => ex diff --git a/app/helpers/action_tracker_helper.rb b/app/helpers/action_tracker_helper.rb index 7d13a5b..b812bbf 100644 --- a/app/helpers/action_tracker_helper.rb +++ b/app/helpers/action_tracker_helper.rb @@ -15,12 +15,12 @@ module ActionTrackerHelper end def join_community_description ta - n_('has joined 1 community:
%{name}', 'has joined %{num} communities:
%{name}', ta.get_resource_name.size) % { + n_('has joined 1 community:
%{name}'.html_safe, 'has joined %{num} communities:
%{name}'.html_safe, ta.get_resource_name.size) % { num: ta.get_resource_name.size, name: ta.collect_group_with_index(:resource_name) do |n,i| - link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")), + link = link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")), ta.get_resource_url[i], title: n - end.join + end.join.html_safe } end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 4a3a1c6..71cad88 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -99,7 +99,6 @@ module ApplicationHelper # # TODO: implement correcly the 'Help' button click def help(content = nil, link_name = nil, options = {}, &block) - link_name ||= _('Help') @help_message_id ||= 1 @@ -122,7 +121,7 @@ module ApplicationHelper button = link_to_function(content_tag('span', link_name), "Element.show('#{help_id}')", options ) close_button = content_tag("div", link_to_function(_("Close"), "Element.hide('#{help_id}')", :class => 'close_help_button')) - 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') + 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') unless block.nil? concat(text) @@ -362,8 +361,8 @@ module ApplicationHelper def popover_menu(title,menu_title,links,html_options={}) html_options[:class] = "" unless html_options[:class] html_options[:class] << " menu-submenu-trigger" - html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false" + html_options[:onclick] = "toggleSubmenu(this, '#{menu_title}', #{CGI::escapeHTML(links.to_json)}); return false".html_safe link_to(content_tag(:span, title), '#', html_options) end @@ -473,9 +472,9 @@ module ApplicationHelper map(&:role) names = [] roles.each do |role| - names << content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}") + names << content_tag('span', role.name, :style => "color: #{role_color(role, resource.environment.id)}").html_safe end - names.join(', ') + safe_join(names, ', ') end def role_color(role, env_id) @@ -911,7 +910,8 @@ module ApplicationHelper end def admin_link - user.is_admin?(environment) ? link_to('' + _('Administration') + '', environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : '' + admin_icon = '' + _('Administration') + '' + user.is_admin?(environment) ? link_to(admin_icon.html_safe, environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : '' end def usermenu_logged_in @@ -920,23 +920,39 @@ module ApplicationHelper if count > 0 pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) end + user_identifier = "#{user.identifier}" + welcome_link = link_to(user_identifier.html_safe, user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage')) + welcome_span = _("Welcome, %s") % welcome_link.html_safe + ctrl_panel_icon = '' + ctrl_panel_section = '' + ctrl_panel_icon + _('Control panel') + '' + ctrl_panel_link = link_to(ctrl_panel_section.html_safe, user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content")) + logout_icon = '' + _('Logout') + '' + logout_link = link_to(logout_icon.html_safe, { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) + join_result = safe_join( + [welcome_span.html_safe, render_environment_features(:usermenu).html_safe, admin_link.html_safe, + manage_enterprises.html_safe, manage_communities.html_safe, ctrl_panel_link.html_safe, + pending_tasks_count.html_safe, logout_link.html_safe], "") + join_result + end - (_("Welcome, %s") % link_to("#{user.identifier}", user.url, :id => "homepage-link", :title => _('Go to your homepage'))) + - render_environment_features(:usermenu) + - admin_link + - manage_enterprises + - manage_communities + - link_to('' + _('Control panel') + '', user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content")) + - pending_tasks_count + - link_to('' + _('Logout') + '', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) + def usermenu_notlogged_in + login_str = '' + _('Login') + '' + ret = _("%s") % modal_inline_link_to(login_str.html_safe, login_url, '#inlineLoginBox', :id => 'link_login') + return ret.html_safe end + def usermenu_signup + signup_str = '' + _('Sign up') + '' + ret = _("or %s") % link_to(signup_str.html_safe, :controller => 'account', :action => 'signup') + return ret.html_safe + + end def limited_text_area(object_name, method, limit, text_area_id, options = {}) - content_tag(:div, [ + content_tag(:div, safe_join([ text_area(object_name, method, { :id => text_area_id, :onkeyup => "limited_text_area('#{text_area_id}', #{limit})" }.merge(options)), content_tag(:p, content_tag(:span, limit) + ' ' + _(' characters left'), :id => text_area_id + '_left'), content_tag(:p, _('Limit of characters reached'), :id => text_area_id + '_limit', :style => 'display: none') - ].join, :class => 'limited-text-area') + ]), :class => 'limited-text-area') end def expandable_text_area(object_name, method, text_area_id, options = {}) @@ -1032,8 +1048,8 @@ module ApplicationHelper end def render_tabs(tabs) - titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') } - contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) } + titles = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') } + contents = tabs.inject(''.html_safe){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) } content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs') end @@ -1051,7 +1067,7 @@ module ApplicationHelper def expirable_link_to(expired, content, url, options = {}) if expired options[:class] = (options[:class] || '') + ' disabled' - content_tag('a', ' '+content_tag('span', content), options) + content_tag('a', ' '.html_safe+content_tag('span', content), options) else if options[:modal] options.delete(:modal) @@ -1084,7 +1100,7 @@ module ApplicationHelper radios = templates.map do |template| 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))) - end.join("\n") + end.join("\n").html_safe content_tag('div', content_tag('label', _('Profile organization'), :for => 'template-options', :class => 'formlabel') + 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 content_tag(:div, :class => 'errorExplanation', :id => 'errorExplanation') do content_tag(:h2, _('Errors while saving')) + content_tag(:ul) do - errors.map { |err| content_tag(:li, err) }.join + safe_join(errors.map { |err| content_tag(:li, err) }) end end end @@ -1234,6 +1250,7 @@ module ApplicationHelper :href=>"#", :title=>_("Exit full screen mode") }) + content.html_safe end end diff --git a/app/helpers/block_helper.rb b/app/helpers/block_helper.rb index 6749b74..089175d 100644 --- a/app/helpers/block_helper.rb +++ b/app/helpers/block_helper.rb @@ -3,13 +3,13 @@ module BlockHelper def block_title(title, subtitle=nil) block_header = block_heading title block_header += block_heading(subtitle, 'h4') if subtitle - content_tag 'div', block_header, :class => 'block-header' + content_tag('div', block_header, :class => 'block-header').html_safe end def block_heading(title, heading='h3') tag_class = 'block-' + (heading == 'h3' ? 'title' : 'subtitle') tag_class += ' empty' if title.empty? - content_tag heading, content_tag('span', h(title)), :class => tag_class + content_tag heading, content_tag('span', h(title)), :class => tag_class.html_safe end def highlights_block_config_image_fields(block, image={}, row_number=nil) diff --git a/app/helpers/blog_helper.rb b/app/helpers/blog_helper.rb index 7fedf87..5805354 100644 --- a/app/helpers/blog_helper.rb +++ b/app/helpers/blog_helper.rb @@ -41,12 +41,12 @@ module BlogHelper css_add << position content << (content_tag 'div', id: "post-#{art.id}", class: css_add do content_tag 'div', class: position + '-inner blog-post-inner' do - display_post(art, conf[:format]).html_safe + - '
'.html_safe + display_post(art, conf[:format]) + + '
' end - end) + end).html_safe } - content.join("\n
\n") + (pagination or '') + safe_join(content, "\n
\n") + (pagination or '').html_safe end def display_post(article, format = 'full') @@ -61,7 +61,8 @@ module BlogHelper else '
' end - end.to_s + title + html + end.to_s.html_safe + + title.html_safe + html end def display_compact_format(article) diff --git a/app/helpers/box_organizer_helper.rb b/app/helpers/box_organizer_helper.rb index 5003cde..6fff9d4 100644 --- a/app/helpers/box_organizer_helper.rb +++ b/app/helpers/box_organizer_helper.rb @@ -38,7 +38,7 @@ module BoxOrganizerHelper content_tag(:ul, images_path.map do |preview| content_tag(:li, image_tag(preview, height: '240', alt: '')) - end.join("\n") + end.join("\n").html_safe ) end diff --git a/app/helpers/boxes_helper.rb b/app/helpers/boxes_helper.rb index b568dc7..9952acd 100644 --- a/app/helpers/boxes_helper.rb +++ b/app/helpers/boxes_helper.rb @@ -44,7 +44,7 @@ module BoxesHelper def display_boxes(holder, main_content) boxes = holder.boxes.with_position.first(boxes_limit(holder)) - content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n") + content = safe_join(boxes.reverse.map { |item| display_box(item, main_content) }, "\n") content = main_content if (content.blank?) content_tag('div', content, :class => 'boxes', :id => 'boxes' ) @@ -54,7 +54,7 @@ module BoxesHelper if holder.respond_to?(element) content_tag('div', holder.send(element), options) else - '' + ''.html_safe end end @@ -70,9 +70,10 @@ module BoxesHelper def display_box_content(box, main_content) context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user, :controller => controller } - box_decorator.select_blocks(box, box.blocks.includes(:box), context).map do |item| + blocks = box_decorator.select_blocks(box, box.blocks.includes(:box), context).map do |item| display_block item, main_content - end.join("\n") + box_decorator.block_target(box) + end + safe_join(blocks, "\n") + box_decorator.block_target(box) end def select_blocks box, arr, context @@ -136,17 +137,18 @@ module BoxesHelper result = filter_html(result, block) - content_tag('div', - box_decorator.block_target(block.box, block) + - content_tag('div', - content_tag('div', - content_tag('div', - result + footer_content + box_decorator.block_edit_buttons(block), - :class => 'block-inner-2'), - :class => 'block-inner-1'), - options), - :class => 'block-outer') + - box_decorator.block_handle(block) + join_result = safe_join([result, footer_content, box_decorator.block_edit_buttons(block)]) + content_tag_inner_1 = content_tag('div', join_result, :class => 'block-inner-2') + + content_tag_inner_2 = content_tag('div', content_tag_inner_1, :class => 'block-inner-1') + content_tag_inner_3 = content_tag('div', content_tag_inner_2, options) + content_tag_inner_4 = box_decorator.block_target(block.box, block) + content_tag_inner_3 + c = content_tag('div', content_tag_inner_4, :class => 'block-outer') + box_decorator_result = box_decorator.block_handle(block) + result_final = safe_join([c, box_decorator_result], "") + + + return result_final end def wrap_main_content(content) @@ -156,17 +158,17 @@ module BoxesHelper def extract_block_content(content) case content when Hash - content_tag('iframe', '', :src => url_for(content)) + content_tag('iframe', ''.html_safe, :src => url_for(content)) when String if content.split("\n").size == 1 and content =~ /^https?:\/\// - content_tag('iframe', '', :src => content) + content_tag('iframe', ''.html_safe, :src => content) else content end when Proc self.instance_eval(&content) when NilClass - '' + ''.html_safe else raise "Unsupported content for block (#{content.class})" end @@ -175,14 +177,14 @@ module BoxesHelper module DontMoveBlocks # does nothing def self.block_target(box, block = nil) - '' + ''.html_safe end # does nothing def self.block_handle(block) - '' + ''.html_safe end def self.block_edit_buttons(block) - '' + ''.html_safe end def self.select_blocks box, arr, context arr = arr.select{ |block| block.visible? context } @@ -229,9 +231,9 @@ module BoxesHelper # makes the given block draggable so it can be moved away. def block_handle(block) return "" unless movable?(block) - icon = "
#{display_icon(block.class)}
#{_(block.class.pretty_name)}
" + icon = "
#{display_icon(block.class)}
#{_(block.class.pretty_name)}
".html_safe block_draggable("block-#{block.id}", - :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}") + :helper => "function() {return cloneDraggableBlock($(this), '#{icon}')}".html_safe) end def block_draggable(element_id, options={}) @@ -302,7 +304,7 @@ module BoxesHelper buttons << modal_inline_icon(:embed, _('Embed code'), {}, "#embed-code-box-#{block.id}") << html end - content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') + content_tag('div', buttons.join("\n").html_safe + tag('br', :style => 'clear: left'), :class => 'button-bar') end def current_blocks diff --git a/app/helpers/buttons_helper.rb b/app/helpers/buttons_helper.rb index 60872a4..7eb46ff 100644 --- a/app/helpers/buttons_helper.rb +++ b/app/helpers/buttons_helper.rb @@ -15,9 +15,9 @@ module ButtonsHelper end the_title = html_options[:title] || label if html_options[:disabled] - content_tag('a', ' '+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title)) + content_tag('a', ' '.html_safe+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title)) else - link_to(' '+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title)) + link_to(' '.html_safe+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title)) end end diff --git a/app/helpers/catalog_helper.rb b/app/helpers/catalog_helper.rb index 839e610..6adc0a9 100644 --- a/app/helpers/catalog_helper.rb +++ b/app/helpers/catalog_helper.rb @@ -19,18 +19,18 @@ module CatalogHelper ancestors = category.ancestors.map { |c| link_to(c.name, {:controller => :catalog, :action => 'index', :level => c.id}) }.reverse current_level = content_tag('strong', category.name) all_items = [start] + ancestors + [current_level] - content_tag('div', all_items.join(' → '), :id => 'breadcrumb') + content_tag('div', safe_join(all_items, ' → '), :id => 'breadcrumb') end def category_link(category) count = profile.products.from_category(category).count name = truncate(category.name, :length => 22 - count.to_s.size) link = link_to(name, {:controller => 'catalog', :action => 'index', :level => category.id}, :title => category.name) - content_tag('div', "#{link} #{count}") if count > 0 + content_tag('div', "#{link} #{count}".html_safe) if count > 0 end def category_with_sub_list(category) - content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}" + content_tag 'li', "#{category_link(category)}\n#{sub_category_list(category)}".html_safe end def sub_category_list(category) @@ -39,7 +39,7 @@ module CatalogHelper cat_link = category_link sub_category sub_categories << content_tag('li', cat_link) unless cat_link.nil? end - content_tag('ul', sub_categories.join) if sub_categories.size > 0 + content_tag('ul', sub_categories.join.html_safe) if sub_categories.size > 0 end end diff --git a/app/helpers/content_viewer_helper.rb b/app/helpers/content_viewer_helper.rb index 1f560d1..e407acc 100644 --- a/app/helpers/content_viewer_helper.rb +++ b/app/helpers/content_viewer_helper.rb @@ -7,7 +7,8 @@ module ContentViewerHelper def display_number_of_comments(n) base_str = "#{n}" amount_str = n == 0 ? _('no comments yet') : (n == 1 ? _('One comment') : _('%s comments') % n) - base_str + "#{amount_str}" + base_str += "#{amount_str}" + base_str.html_safe end def number_of_comments(article) @@ -19,11 +20,11 @@ module ContentViewerHelper title = content_tag('h1', h(title), :class => 'title') if article.belongs_to_blog? || article.belongs_to_forum? unless args[:no_link] - title = content_tag('h1', link_to(article.name, article.url), :class => 'title') + title = content_tag('h1', link_to(article.name, url_for(article.url)), :class => 'title') end comments = '' unless args[:no_comments] || !article.accept_comments - comments = (" - %s") % link_to_comments(article) + comments = (" - %s").html_safe % link_to_comments(article) end date_format = show_with_right_format_date article title << content_tag('span', diff --git a/app/helpers/display_helper.rb b/app/helpers/display_helper.rb index a0514d6..97f3054 100644 --- a/app/helpers/display_helper.rb +++ b/app/helpers/display_helper.rb @@ -53,18 +53,19 @@ module DisplayHelper end def txt2html(txt) - txt.strip. + ret = txt.strip. gsub( /\s*\n\s*\n\s*/, "\r

\r" ). gsub( /\s*\n\s*/, "\n
\n" ). gsub( /\r/, "\n" ). gsub( /(^|\s)(www\.[^\s]+|https?:\/\/[^\s]+)/ ) do pre_char, href = $1, $2 href = 'http://'+href if ! href.match /^https?:/ - content = href.gsub(/^https?:\/\//, '').scan(/.{1,4}/).join('​') + content = safe_join(href.gsub(/^https?:\/\//, '').scan(/.{1,4}/), '​'.html_safe) pre_char + content_tag(:a, content, :href => href, :target => '_blank', - :rel => 'nofolow', :onclick => "return confirm('%s')" % + :rel => 'nofolow', :onclick => "return confirm('%s')".html_safe % _('Are you sure you want to visit this web site?')) end + ret.html_safe end end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 7c89e47..0b33cdb 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -1,13 +1,17 @@ module EventsHelper include DatesHelper + include ActionView::Helpers::OutputSafetyHelper + def list_events(date, events) title = _('Events for %s') % show_date_month(date) + user_events = events.select { |item| item.display_to?(user) } + events_for_month = safe_join(user_events.map {|item| display_event_in_listing(item)}, '') content_tag('h2', title) + content_tag('div', (events.any? ? - content_tag('table', events.select { |item| item.display_to?(user) }.map {|item| display_event_in_listing(item)}.join('')) : - content_tag('em', _('No events for this month'), :class => 'no-events') + content_tag('table', events_for_month) : + content_tag('em', _('No events for this month'), :class => 'no-events') ), :id => 'agenda-items' ) end diff --git a/app/helpers/forms_helper.rb b/app/helpers/forms_helper.rb index 36f6885..142fad7 100644 --- a/app/helpers/forms_helper.rb +++ b/app/helpers/forms_helper.rb @@ -101,7 +101,7 @@ module FormsHelper def required_fields_message content_tag('p', content_tag('span', - _("The fields are mandatory."), + _("The fields are mandatory.").html_safe, :class => 'required-field' )) end @@ -112,10 +112,11 @@ module FormsHelper options_for_select = container.inject([]) do |options, element| text, value = option_text_and_value(element) selected_attribute = ' selected="selected"' if option_value_selected?(value, selected) - options << %() + opt = %() + options << opt.html_safe end - options_for_select.join("\n") + safe_join(options_for_select, "\n") end def balanced_table(items, per_row=3) @@ -248,8 +249,8 @@ module FormsHelper def date_range_field(from_name, to_name, from_value, to_value, datepicker_options = {}, html_options = {}) from_id = html_options[:from_id] || 'datepicker-from-date' to_id = html_options[:to_id] || 'datepicker-to-date' - return _('From') +' '+ date_field(from_name, from_value, datepicker_options, html_options.merge({:id => from_id})) + - ' ' + _('until') +' '+ date_field(to_name, to_value, datepicker_options, html_options.merge({:id => to_id})) + return (_('From') +' '+ date_field(from_name, from_value, datepicker_options, html_options.merge({:id => from_id})) + + ' ' + _('until') +' '+ date_field(to_name, to_value, datepicker_options, html_options.merge({:id => to_id}))).html_safe end def select_folder(label_text, field_id, collection, default_value=nil, html_options = {}, js_options = {}) diff --git a/app/helpers/forum_helper.rb b/app/helpers/forum_helper.rb index a2ff7d9..619185f 100644 --- a/app/helpers/forum_helper.rb +++ b/app/helpers/forum_helper.rb @@ -35,7 +35,7 @@ module ForumHelper :id => "post-#{art.id}" ) } - content_tag('table', content.join) + (pagination or '') + content_tag('table', safe_join(content, "")) + (pagination or '').html_safe end def last_topic_update(article) diff --git a/app/helpers/language_helper.rb b/app/helpers/language_helper.rb index 889be0c..d52f29e 100644 --- a/app/helpers/language_helper.rb +++ b/app/helpers/language_helper.rb @@ -40,7 +40,7 @@ module LanguageHelper else link_to(name, params.merge(:lang => code), :rel => 'nofollow') end - end.join(separator) + end.join(separator).html_safe 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.')) end end diff --git a/app/helpers/layout_helper.rb b/app/helpers/layout_helper.rb index 57687c7..d1ab1a8 100644 --- a/app/helpers/layout_helper.rb +++ b/app/helpers/layout_helper.rb @@ -40,7 +40,8 @@ module LayoutHelper output += templete_javascript_ng.to_s - output + # This output should be safe! + output.html_safe end def noosfero_stylesheets @@ -64,7 +65,9 @@ module LayoutHelper output << stylesheet_link_tag(global_css_pub) end output << stylesheet_link_tag(theme_stylesheet_path) - output.join "\n" + + # This output should be safe! + output.join("\n").html_safe end def noosfero_layout_features diff --git a/app/helpers/manage_products_helper.rb b/app/helpers/manage_products_helper.rb index 2fe2755..9e44e86 100644 --- a/app/helpers/manage_products_helper.rb +++ b/app/helpers/manage_products_helper.rb @@ -38,10 +38,11 @@ module ManageProductsHelper end def options_for_select_categories(categories, selected = nil) - categories.sort_by{|cat| cat.name.transliterate}.map do |category| - selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '') - "" - end.join("\n") + safe_join(categories.sort_by{ |cat| + cat.name.transliterate}.map do |category| + selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '') + "".html_safe + end, "\n") end def build_selects_for_ancestors(ancestors, current_category) @@ -76,10 +77,13 @@ module ManageProductsHelper def categories_container(categories_selection_html, hierarchy_html = '') content_tag 'div', - render('categories_autocomplete') + - hidden_field_tag('selected_category_id') + - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') + - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'), + safe_join( + [ + render('categories_autocomplete'), + hidden_field_tag('selected_category_id'), + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation'), + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper') + ], ''), :id => 'categories-container' end diff --git a/app/helpers/profile_editor_helper.rb b/app/helpers/profile_editor_helper.rb index 30f4f35..ec7dab9 100644 --- a/app/helpers/profile_editor_helper.rb +++ b/app/helpers/profile_editor_helper.rb @@ -129,7 +129,11 @@ module ProfileEditorHelper else domains = environment.domains end - labelled_form_field(_('Preferred domain name:'), select(object, :preferred_domain_id, domains.map {|item| [item.name, item.id]}, :prompt => '<' + _('Select domain') + '>')) + select_domain_prompt = '<'.html_safe + _('Select domain').html_safe + '>'.html_safe + select_field = select(object, :preferred_domain_id, domains.map { + |item| [item.name, item.id]}, :prompt => select_domain_prompt.html_safe) + + labelled_form_field(_('Preferred domain name:'), select_field) end def control_panel(&block) diff --git a/app/helpers/profile_image_helper.rb b/app/helpers/profile_image_helper.rb index 563af12..15f6410 100644 --- a/app/helpers/profile_image_helper.rb +++ b/app/helpers/profile_image_helper.rb @@ -131,7 +131,7 @@ module ProfileImageHelper links = links_for_balloon(profile) content_tag('div', content_tag(tag, (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? - popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "") + + popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "").html_safe + link_to( content_tag( 'span', profile_image( profile, size ), :class => img_class ) + content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) + @@ -139,7 +139,7 @@ module ProfileImageHelper profile.url, :class => 'profile_link url', :help => _('Click on this icon to go to the %s\'s home page') % profile.name, - :title => profile.name ), + :title => profile.name ).html_safe, :class => 'vcard'), :class => 'common-profile-list-block') end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 219678b..6b55890 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -124,10 +124,10 @@ module SearchHelper def filters(asset) return if !asset klass = asset_class(asset) - content_tag('div', klass::SEARCH_FILTERS.map do |name, options| + content_tag('div', safe_join(klass::SEARCH_FILTERS.map do |name, options| default = klass.respond_to?("default_search_#{name}") ? klass.send("default_search_#{name}".to_s) : nil select_filter(name, options, default) - end.join("\n"), :id => 'search-filters') + end, "\n"), :id => 'search-filters') end def assets_menu(selected) @@ -137,11 +137,11 @@ module SearchHelper # menu. assets.delete(:events) content_tag('ul', - assets.map do |asset| + safe_join(assets.map do |asset| options = {} options.merge!(:class => 'selected') if selected.to_s == asset.to_s content_tag('li', asset_link(asset), options) - end.join("\n"), + end, "\n"), :id => 'assets-menu') end diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb index 8238a35..1308cf4 100644 --- a/app/helpers/tags_helper.rb +++ b/app/helpers/tags_helper.rb @@ -58,7 +58,7 @@ module TagsHelper if options[:show_count] display_count = options[:show_count] ? "(#{count})" : "" - link_to tag + display_count, destination, :style => style + link_to (tag + display_count).html_safe, destination, :style => style else link_to h(tag) , destination, :style => style, :title => n_( 'one item', '%d items', count ) % count diff --git a/app/helpers/tinymce_helper.rb b/app/helpers/tinymce_helper.rb index c17c97c..4f4feca 100644 --- a/app/helpers/tinymce_helper.rb +++ b/app/helpers/tinymce_helper.rb @@ -7,7 +7,7 @@ module TinymceHelper output += javascript_include_tag 'tinymce/js/tinymce/jquery.tinymce.min.js' output += javascript_include_tag 'tinymce.js' output += include_macro_js_files.to_s - output + output.html_safe end def tinymce_init_js options = {} @@ -37,7 +37,7 @@ module TinymceHelper #cleanup non tinymce options options = options.except :mode - "noosfero.tinymce.init(#{options.to_json})" + "noosfero.tinymce.init(#{options.to_json})".html_safe end def menubar mode diff --git a/app/models/approve_article.rb b/app/models/approve_article.rb index 803cbe3..2903a04 100644 --- a/app/models/approve_article.rb +++ b/app/models/approve_article.rb @@ -86,7 +86,7 @@ class ApproveArticle < Task def information if article - {:message => _('%{requestor} wants to publish the article: %{linked_subject}.')} + {:message => _('%{requestor} wants to publish the article: %{linked_subject}.').html_safe} else {:message => _("The article was removed.")} end diff --git a/app/models/create_community.rb b/app/models/create_community.rb index 1720ddd..f273655 100644 --- a/app/models/create_community.rb +++ b/app/models/create_community.rb @@ -60,9 +60,9 @@ class CreateCommunity < Task def information if description.blank? - { :message => _('%{requestor} wants to create community %{subject} with no description.') } + { :message => _('%{requestor} wants to create community %{subject} with no description.').html_safe } else - { :message => _('%{requestor} wants to create community %{subject} with this description:

%{description}

'), + { :message => _('%{requestor} wants to create community %{subject} with this description:

%{description}

').html_safe, :variables => {:description => description} } end end diff --git a/app/models/create_enterprise.rb b/app/models/create_enterprise.rb index 0cbc00c..d415d0c 100644 --- a/app/models/create_enterprise.rb +++ b/app/models/create_enterprise.rb @@ -163,7 +163,7 @@ class CreateEnterprise < Task end def information - {:message => _('%{requestor} wants to create enterprise %{subject}.')} + {:message => _('%{requestor} wants to create enterprise %{subject}.').html_safe} end def reject_details diff --git a/app/models/doc_item.rb b/app/models/doc_item.rb index 9c68e06..84a50a3 100644 --- a/app/models/doc_item.rb +++ b/app/models/doc_item.rb @@ -17,7 +17,7 @@ class DocItem else match end - end + end.html_safe end private diff --git a/app/models/environment.rb b/app/models/environment.rb index b59dce4..10998a2 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -729,7 +729,7 @@ class Environment < ActiveRecord::Base url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname) url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port) url << Noosfero.root('') - url + url.html_safe end def to_s diff --git a/app/models/invite_friend.rb b/app/models/invite_friend.rb index b74b0bc..f845901 100644 --- a/app/models/invite_friend.rb +++ b/app/models/invite_friend.rb @@ -13,7 +13,7 @@ class InviteFriend < Invitation end def information - {:message => _('%{requestor} wants to be your friend.')} + {:message => _('%{requestor} wants to be your friend.').html_safe} end def accept_details @@ -25,7 +25,7 @@ class InviteFriend < Invitation end def target_notification_description - _('%{requestor} wants to be your friend.') % {:requestor => requestor.name} + (_('%{requestor} wants to be your friend.') % {:requestor => requestor.name}).html_safe end def permission diff --git a/app/models/invite_member.rb b/app/models/invite_member.rb index 69212b7..b7eceed 100644 --- a/app/models/invite_member.rb +++ b/app/models/invite_member.rb @@ -25,7 +25,7 @@ class InviteMember < Invitation end def information - {:message => _('%{requestor} invited you to join %{linked_subject}.')} + {:message => _('%{requestor} invited you to join %{linked_subject}.').html_safe} end def url @@ -37,7 +37,7 @@ class InviteMember < Invitation end def target_notification_description - _('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name} + (_('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name}).html_safe end def target_notification_message diff --git a/app/models/profile.rb b/app/models/profile.rb index d99354a..ca2b4c2 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -646,7 +646,7 @@ class Profile < ActiveRecord::Base url << url_options[:host] url << ':' << url_options[:port].to_s if url_options.key?(:port) url << Noosfero.root('') - url + url.html_safe end private :generate_url, :url_options diff --git a/app/models/suggest_article.rb b/app/models/suggest_article.rb index a858b83..63e87b8 100644 --- a/app/models/suggest_article.rb +++ b/app/models/suggest_article.rb @@ -65,7 +65,7 @@ class SuggestArticle < Task def information variables = requestor.blank? ? {:requestor => sender} : {} - { :message => _('%{requestor} suggested the publication of the article: %{subject}.'), + { :message => _('%{requestor} suggested the publication of the article: %{subject}.').html_safe, :variables => variables } end @@ -78,7 +78,7 @@ class SuggestArticle < Task end def target_notification_description - _('%{requestor} suggested the publication of the article: %{article}.') % + _('%{requestor} suggested the publication of the article: %{article}.').html_safe % {:requestor => sender, :article => article_name} end diff --git a/app/views/account/_signup_form.html.erb b/app/views/account/_signup_form.html.erb index 49c08d1..310f616 100644 --- a/app/views/account/_signup_form.html.erb +++ b/app/views/account/_signup_form.html.erb @@ -107,7 +107,7 @@ <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %> <% end %> - <%= @plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }.join("") %> + <%= safe_join(@plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }, "") %> <%= template_options(:people, 'profile_data') %> diff --git a/app/views/account/activate_enterprise.html.erb b/app/views/account/activate_enterprise.html.erb index 192013d..1735603 100644 --- a/app/views/account/activate_enterprise.html.erb +++ b/app/views/account/activate_enterprise.html.erb @@ -14,7 +14,7 @@ - <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_exec(&content) }.join("") %> + <%= safe_join(@plugins.dispatch(:login_extra_contents).collect { |content| instance_exec(&content) }, "") %> <% button_bar do %> <%= submit_button( 'login', _('Log in') )%> diff --git a/app/views/account/login_block.html.erb b/app/views/account/login_block.html.erb index 85ecf78..8298c96 100644 --- a/app/views/account/login_block.html.erb +++ b/app/views/account/login_block.html.erb @@ -15,7 +15,7 @@ <%= f.password_field :password %> - <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_eval(&content) }.join("") %> + <%= safe_join(@plugins.dispatch(:login_extra_contents).collect { |content| instance_eval(&content) }, "") %> <% button_bar do %> <%= submit_button( 'login', _('Log in') )%> diff --git a/app/views/account/new_password_ok.html.erb b/app/views/account/new_password_ok.html.erb index 2bed21a..64d0694 100644 --- a/app/views/account/new_password_ok.html.erb +++ b/app/views/account/new_password_ok.html.erb @@ -5,5 +5,5 @@

-<%= _("You can login now.") % url_for(:action => 'login') %> +<%= _("You can login now.").html_safe % url_for(:action => 'login') %>

diff --git a/app/views/blocks/blog_archives.html.erb b/app/views/blocks/blog_archives.html.erb index 624e27f..0934105 100644 --- a/app/views/blocks/blog_archives.html.erb +++ b/app/views/blocks/blog_archives.html.erb @@ -6,7 +6,7 @@ <%= content_tag('li', content_tag('strong', "#{year.to_i} (#{count})")) %> <% end %> diff --git a/app/views/blocks/link_list.html.erb b/app/views/blocks/link_list.html.erb index 8e1eedf..1c2c072 100644 --- a/app/views/blocks/link_list.html.erb +++ b/app/views/blocks/link_list.html.erb @@ -8,7 +8,7 @@ <%= block.sanitize_link(link_to(link[:name], block.expand_address(link[:address]), :target => link[:target], :class => (link[:icon] ? "icon-#{link[:icon]}" : ''), - :title => link[:title])) %> + :title => link[:title])).html_safe %> <% end %> diff --git a/app/views/blocks/login.html.erb b/app/views/blocks/login.html.erb index ed8e1e1..29a8c3e 100644 --- a/app/views/blocks/login.html.erb +++ b/app/views/blocks/login.html.erb @@ -3,7 +3,7 @@

<%= _('Logged in as %s') % user.identifier %>

<%= button(:'menu-logout', _('Logout'), :controller => 'account', :action => 'logout') %> diff --git a/app/views/blocks/profile_list.html.erb b/app/views/blocks/profile_list.html.erb index a09dec8..02fdc15 100644 --- a/app/views/blocks/profile_list.html.erb +++ b/app/views/blocks/profile_list.html.erb @@ -10,8 +10,8 @@ <% if list.empty? %>
<%= _('None') %>
<% else %> - + <% end %>
- +
diff --git a/app/views/box_organizer/_article_block.html.erb b/app/views/box_organizer/_article_block.html.erb index 90b4e29..eecbd36 100644 --- a/app/views/box_organizer/_article_block.html.erb +++ b/app/views/box_organizer/_article_block.html.erb @@ -9,7 +9,8 @@ first_text = articles[articles.find_index{|a| a.kind_of? TextArticle}||-1] selected = @block.article || first_text %> - <%= select_tag( + <%= + select_tag( 'block[article_id]', options_for_select_with_title(articles.map {|item| [item.path, item.id]}, selected.id), :onchange => 'this.changedTo(this.value)' diff --git a/app/views/catalog/index.html.erb b/app/views/catalog/index.html.erb index 7525479..f22a3e8 100644 --- a/app/views/catalog/index.html.erb +++ b/app/views/catalog/index.html.erb @@ -35,7 +35,7 @@ <% else %>
<%= _('No image') %>
<% end %> -
<%= extra_content.join("\n") %>
+
<%= safe_join(extra_content, "\n") %>
diff --git a/app/views/cms/_blog.html.erb b/app/views/cms/_blog.html.erb index 5124ff8..4c67959 100644 --- a/app/views/cms/_blog.html.erb +++ b/app/views/cms/_blog.html.erb @@ -35,7 +35,7 @@
<%= labelled_form_field( _('Address'), content_tag('code', - url_for(@article.url).gsub(/#{@article.slug}$/, '') + + url_for(@article.url).gsub(/#{@article.slug}$/, '').html_safe + text_field(:article, :slug, :onchange => "warn_value_change()", :size => 25) ) + content_tag('div', diff --git a/app/views/cms/_textile_quick_reference.html.erb b/app/views/cms/_textile_quick_reference.html.erb index db524b4..8d13d1d 100644 --- a/app/views/cms/_textile_quick_reference.html.erb +++ b/app/views/cms/_textile_quick_reference.html.erb @@ -14,7 +14,7 @@

<%= _('Numbered lists:') %>

# <%= _('first item') %>
 # <%= _('second item') %>
-

<%= h(_('For code, use HTML tags

 and , and indent the code inside them:')) %>
+    

<%= h(_('For code, use HTML tags

 and , and indent the code inside them:').html_safe) %>
     

 <pre>
@@ -23,7 +23,7 @@
 </code>
 </pre>
 
-

<%= _('See also a more complete Textile Reference.') % 'http://redcloth.org/hobix.com/textile/' %>

+

<%= _('See also a more complete Textile Reference.').html_safe % 'http://redcloth.org/hobix.com/textile/' %>

diff --git a/app/views/cms/edit.html.erb b/app/views/cms/edit.html.erb index 3fdfd4b..9da4fb0 100644 --- a/app/views/cms/edit.html.erb +++ b/app/views/cms/edit.html.erb @@ -39,7 +39,7 @@ diff --git a/app/views/cms/select_article_type.html.erb b/app/views/cms/select_article_type.html.erb index 23a78c4..8e888dc 100644 --- a/app/views/cms/select_article_type.html.erb +++ b/app/views/cms/select_article_type.html.erb @@ -5,7 +5,7 @@ - <%= @toc.text %> + <%= raw @toc.text %> diff --git a/app/views/features/index.html.erb b/app/views/features/index.html.erb index 9280cd1..90c7009 100644 --- a/app/views/features/index.html.erb +++ b/app/views/features/index.html.erb @@ -5,7 +5,7 @@

<%= _('Here you can enable or disable several features of your environment. Each feature represents some funcionality that your environment can use if you enable it. -Check all the features you want to enable for your environment, uncheck all the ones you don\'t want, and use the "Save changes" button to confirm your changes.') %> +Check all the features you want to enable for your environment, uncheck all the ones you don\'t want, and use the "Save changes" button to confirm your changes.').html_safe %>

<%= labelled_form_for(:environment, :url => {:action => 'update'}) do |f| %> diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index f2d3bd2..2ae6e58 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -7,7 +7,7 @@

<%= link_to(h(highlighted.title), highlighted.url, :class => 'post-title') %>

-
<%= highlighted.lead %>
+
<%= raw highlighted.lead %>

<%= link_to(_('Read more'), highlighted.url) %>

@@ -49,7 +49,7 @@ <% end %> <% end %> <% else %> - <%= environment.description %> + <%= environment.description.html_safe %> <% end %> <% if environment.enabled?('search_in_home') %> diff --git a/app/views/invite/_select_address_book.html.erb b/app/views/invite/_select_address_book.html.erb index 07a567c..285cc64 100644 --- a/app/views/invite/_select_address_book.html.erb +++ b/app/views/invite/_select_address_book.html.erb @@ -3,12 +3,12 @@ <%= form_tag do %> - <%= [ + <%= safe_join([ 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"), 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'), 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"), 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") - ].join("\n
\n") %> + ], "\n
\n".html_safe) %> <%= _("Go to the content") %> - <%= - @plugins.dispatch(:body_beginning).map do |content| - if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end - end.join("\n") + str = (@plugins.dispatch(:body_beginning).map do |content| + if content.respond_to?(:call) then + instance_exec(&content).to_s + else + content.to_s + end + end) + safe_join(str, "\n") %>
<% extra_content = @plugins.dispatch(:product_info_extras, @product).collect { |content| instance_exec(&content) } %> - <%= extra_content.join("\n") %> + <%= safe_join(extra_content, "\n") %>
<%= render :partial => 'manage_products/display_info' %> diff --git a/app/views/memberships/new_community.html.erb b/app/views/memberships/new_community.html.erb index 338a0ac..ef77082 100644 --- a/app/views/memberships/new_community.html.erb +++ b/app/views/memberships/new_community.html.erb @@ -34,13 +34,13 @@
<%= radio_button 'community', 'closed', 'true', :style => 'float: left' %>
- <%= _('Before joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).') %> + <%= _('Before joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).').html_safe %>
<%= radio_button 'community', 'closed', 'false', :style => 'float: left' %>
- <%= _('After joining this group (a moderator can always desactivate access for users later).') %> + <%= _('After joining this group (a moderator can always desactivate access for users later).').html_safe %>
diff --git a/app/views/pending_task_notifier/notification.text.erb b/app/views/pending_task_notifier/notification.text.erb index e6f5b15..2040555 100644 --- a/app/views/pending_task_notifier/notification.text.erb +++ b/app/views/pending_task_notifier/notification.text.erb @@ -2,7 +2,7 @@ <%= _("You have %d pending task(s).") % @tasks.size %> -<%= @tasks.map{|i| " * #{i.description}"}.join("\n") %> +<%= safe_join(@tasks.map{|i| " * #{i.description}"}, "\n") %> <%= _("Click in address below to process task(s):") %> @@ -11,7 +11,7 @@ <% pending_tasks = @person.pending_tasks_for_organization(organization) %> <%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %> -<%= pending_tasks.map{|i| " * #{i.information}"}.join("\n") %> +<%= safe_join(pending_tasks.map{|i| " * #{i.information}"}, "\n") %> <%= _("Click in address below to process task(s):") %> diff --git a/app/views/profile/content_tagged.html.erb b/app/views/profile/content_tagged.html.erb index 4fa8f0c..a507447 100644 --- a/app/views/profile/content_tagged.html.erb +++ b/app/views/profile/content_tagged.html.erb @@ -20,6 +20,6 @@ <%= pagination_links @tagged, :param_name => 'npage' %>
- <%= link_to _('See content tagged with "%s" in the entire site') % escaped_tag, :controller => 'search', :action => 'tag', :tag => @tag %> + <%= link_to (_('See content tagged with "%s" in the entire site') % escaped_tag).html_safe, :controller => 'search', :action => 'tag', :tag => @tag %>
<% end %> diff --git a/app/views/profile/index.html.erb b/app/views/profile/index.html.erb index 9f659a4..fb9a430 100644 --- a/app/views/profile/index.html.erb +++ b/app/views/profile/index.html.erb @@ -5,7 +5,7 @@ <% else %> <% unless profile.description.blank? %>
- <%= profile.description %> + <%= raw profile.description %>
<% end %>