Rails HTML Permit Sanitizer не работает, как я ожидал - PullRequest
0 голосов
/ 15 мая 2018

Я застрял, пытаясь понять, как использовать дезинфицирующее средство Rails. Кажется, он работает не так, как я ожидал. Думаю, я что-то неправильно понимаю.

В основном я пытаюсь очистить все divs, кроме divs, которые имеют атрибут со значением highlight. Но ради примера я попытался использовать PermitScrubber сам по себе.

Я устанавливаю свои теги и атрибуты и наследую от PermitScrubber, но в любом случае он очищает мои разрешенные теги и атрибуты:

class ExampleScrubber < Rails::Html::PermitScrubber
  def initialize
    super
    self.tags = %w(img),
    self.attributes = %w(src alt)
  end

  # commented out for the example, but what I'm trying to ultimately do
  # def allowed_node?(node)
    # node.name == "div" && node.attributes.values.first.value = "highlight"
  # end
end

@comment.body = "<ul>\n<li>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n"
ActionController::Base.helpers.sanitize(
  @comment.body,
  scrubber: ExampleScrubber.new
)
#=> "\nyes\ntests\n\n\n\n"

Итак, две вещи: 1. Почему выполняется очистка тегов img и атрибутов src и alt? 2. Я знаю, что могу реорганизовать метод allowed_node?, но сначала я хочу выяснить номер один.

Спасибо за чтение 101

1 Ответ

0 голосов
/ 15 мая 2018

Первая проблема («Почему [это] очищает тег img и атрибуты src и alt?») Вызвана случайной запятой после массива.

#             Here v
self.tags = %w(img),

TIL Ruby не требует квадратных скобок для массивов:

a = "b", "c" # => ["b", "c"]

Итак, эта запятая превращает ваш tags в массив массивов:

ExampleScrubber.new.tags # => [["img"], ["src", "alt"]]

Что вызывает проблемы и позволяет очистить тег. Удаление запятой заставляет вещи работать правильно:

class ExampleScrubber < Rails::Html::PermitScrubber
  def initialize
    super
    self.tags = %w(img)
    self.attributes = %w(src alt)
  end

  # commented out for the example, but what I'm trying to ultimately do
  # def allowed_node?(node)
    # node.name == "div" && node.attributes.values.first.value = "highlight"
  # end
end

body = "<ul>\n<li>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n"
ActionController::Base.helpers.sanitize(body, scrubber: ExampleScrubber.new)
# => "\nyes\ntests\n\n\n<img src=\"something.jpeg\" alt=\"something\">\n"

Таким образом, чтобы достичь своей цели, сохранить только divs и только если у них есть атрибут (любой атрибут), включая слово «выделение», вы можете попробовать что-то вроде:

class ExampleScrubber < Rails::Html::PermitScrubber
  def initialize
    super
    self.tags = %w( div )
  end

  def allowed_node?(node)
    @tags.include?(node.name) && node.attributes.values.any? do |attribute_value|
      attribute_value.value.include?('highlight')
    end
  end
end

body = "<ul>\n<li class='highlight'>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n<div class='highlight'>Something</div><div>Else</div>"
results = ActionController::Base.helpers.sanitize(body, scrubber: ExampleScrubber.new)
# => "\nyes\ntests\n\n\n\n<div class=\"highlight\">Something</div>Else"
...