HTML ускользнул в Rails 3 - PullRequest
       1

HTML ускользнул в Rails 3

1 голос
/ 11 октября 2010

У меня есть вызов метода на мой взгляд, как это

<%= Navigation.with(params) do |menu| 
              if current_user && current_user.can_verify?
                menu.item("Listings", manage_listings_path())
                menu.item("Listing changes", needing_change_approval_manage_listings_path())
                menu.item("Flagged Items", flagged_manage_listings_path())
                menu.item("Transfers", manage_listing_transfers_path())
                menu.item("Reviews", manage_listing_reviews_path())
              end
              if current_user && current_user.admin?
                menu.item("Log", manage_verifications_path())
                menu.item("Indexer Compensations", manage_compensations_path())
                menu.item("Users", manage_users_path())
              end
            end%>

, который разбивает строку ниже

"<li><a href="/manage/listings" class="active">Listings</a></li> <li><a href="/manage/listings/needing_change_approval">Listing changes</a></li> <li><a href="/manage/listings/flagged">Flagged Items</a></li> <li><a href="/manage/listing_transfers">Transfers</a></li> <li><a href="/manage/listing_reviews">Reviews</a></li> <li><a href="/manage/verifications">Log</a></li> <li><a href="/manage/compensations">Indexer Compensations</a></li> <li><a href="/manage/users">Users</a></li>"

Я просто получаю эту строку на своей странице.Я хотел, чтобы они были в стиле CSS.Я просто получаю вышеуказанный необработанный текст на своей странице.Как преобразовать эту строку, чтобы браузер обрабатывал ее как HTML.

Пожалуйста, помогите

Вот класс навигации

class NavigationMenu < ActionView::Base
  def initialize(params)
    @params = params
  end

  def item(title, path, options={})
    @items ||= Array.new
    unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
      raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
    end

    @items << content_tag(:li, link_to(title,path, :class => (@params[:controller] == route[:controller] && @params[:action] == route[:action])? 'active' : nil))

  end

  def output
    return '' if @items.blank?
    content_tag(:ul, @items.join("\n"), :id => 'navigation')
  end
end

class Navigation
  def self.with(params, &block)
    menu = NavigationMenu.new(params)
    yield menu
    menu.output
  end
end

Ответы [ 4 ]

9 голосов
/ 11 октября 2010

Вы должны добавить вызов к методу raw:

<%= raw ... %>

Это необходимо, потому что в Rails 3 каждая строка экранируется по умолчанию, если вы не используете метод raw.Это похоже на метод h в Rails 2, где каждая строка по умолчанию не экранирована, если только вы не используете метод h.

Пример:

Этот код в Rails 2 ...

<%= h "String which must be escaped" %>
<%= "String which must be output raw %>

... должен быть таким в Rails 3:

<%= "String which must be escaped" %>
<%= raw "String which must be output raw %>

(Хотя дополнительный вызов h не делаетлюбой вред в Rails 3)

4 голосов
/ 11 октября 2010

Вам нужно добавить .html_safe к строке - это остановит рельсы от выхода из нее, когда пришло время выводить текст. Вероятно, лучше всего поместить его в метод item, который вы вызываете повторно.

1 голос
/ 10 февраля 2012

Недавно я написал статью о защите XSS в Rails 3 при обновлении с Rails 2: http://developer.uservoice.com/entries/upgrading-to-rails-3-printing-escaped-strings

Идея состоит в том, чтобы привязать код к печати HTML, чтобы мы могли определить, когда мы на самом деле печатаем то, что нам не нужно:

module ActionView
  module Helpers
    module TextHelper

      def simple_format_with_double_escape_reporting(*args)
        HtmlDoubleEscapeReporter.assert_sane(simple_format_without_double_escape_reporting(*args))
      end 
      alias_method_chain :simple_format, :double_escape_reporting
    end 

    module TagHelper
      private
      def content_tag_string_with_double_escape_reporting(*args)
        HtmlDoubleEscapeReporter.assert_sane(content_tag_string_without_double_escape_reporting(*args))
      end 
      alias_method_chain :content_tag_string, :double_escape_reporting
    end 
    module UrlHelper
      def link_to_with_double_escape_reporting(*args, &block)
        HtmlDoubleEscapeReporter.assert_sane(link_to_without_double_escape_reporting(*args, &block))
      end 
      alias_method_chain :link_to, :double_escape_reporting
    end 
  end 
end

Метод HtmlDoubleEscapeReporter.assert_sane можно записать, например, так:

class HtmlDoubleEscapeReporter
  def self.assert_sane(str)
    if (str.match(/&lt;[a-z]/) || str.match(/&amp;(quot|rarr|larr|amp|#)/)) &&
        !str.match(/looks something you do not want to print/
      send_problem_report('#{str}' looks something you do not want to print")
    end
    return str
  end
end

Здесь «выглядит то, что вы не хотите печатать», используется для предотвращения возможности бесконечных циклов. Строка send_problem_report ('# {str}' выглядит как то, что вы не хотите печатать ") может быть заменена вызовом" debugger "(из гема ruby-debug), чтобы вы могли проверить обратную трассировку и посмотреть, где проблема исходит от.

0 голосов
/ 11 октября 2010

Вот новый класс. Наконец-то ... Я получил эту ошибку.

class NavigationMenu < ActionView::Base
  def initialize(params)
    @params = params
  end

  def item(title, path, options={})
    @items ||= Array.new
    unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
      raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
    end

    @items << content_tag(:li, link_to(title,path, :class => (@params[:controller] == route[:controller] && @params[:action] == route[:action])? 'active' : nil))

  end

  def output
    @items = @items.join("\n").html_safe
    return '' if @items.blank?
    content_tag(:ul, @items, :id => 'navigation')
  end
end

class Navigation
  def self.with(params, &block)
    menu = NavigationMenu.new(params)
    yield menu
    menu.output
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...