Почему происходит сбой URI.escape при вызове в ActionView :: OutputBuffer? - PullRequest
14 голосов
/ 27 февраля 2012

Я обновляю приложение с Rails 2 до Rails 3. Судя по всему, вызов render() теперь возвращает ActionView::OutputBuffer, а не String.Мне нужно передать результаты render() в URI.escape(), и это не сработало за исключением ...

Вот мое краткое тестирование в консоли

ob = ActionView::OutputBuffer.new("test test")
URI.escape(ob)
    `NoMethodError: undefined method 'each_byte' for nil:NilClass`. 
        from /opt/ruby19/lib/ruby/1.9.1/uri/common.rb:307:in `block in escape'
        from ..../ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/core_ext/string/output_safety.rb:160:in `gsub'
        from ..../ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/core_ext/string/output_safety.rb:160:in `gsub'
        from /opt/ruby19/lib/ruby/1.9.1/uri/common.rb:304:in `escape'
        from /opt/ruby19/lib/ruby/1.9.1/uri/common.rb:623:in `escape'

Более того, вызов to_sв OutputBuffer возвращает тот же класс OutputBuffer, поэтому я даже не могу преобразовать этот буфер в честную строку?

ob.to_s.class 
    ActionView::OutputBuffer

Конечно, вызов URI.escape ("test test") возвращает "test% 20test", как и ожидалось,так что это не проблема URI.

Среда:

  • ruby ​​1.9.3p125 (2012-02-16, редакция 34643) [i686-linux]
  • Rails 3.2.1

Мой вопрос: Почему это происходит и как я могу обойти эту проблему?

Обновление: Видимо,использование '' + ob в качестве формы ob.to_s преобразует OutputBuffer в String, что эффективно решает проблему ... Но мой вопрос ', почему это происходит ' все еще остается, например, если это ошибка, следуетЯ сообщаю об этом, или я делаю что-то не так?

Ответы [ 3 ]

19 голосов
/ 27 февраля 2012

Это ошибка в Rails :

При вызове gsub с блоком в ActiveSupport :: SafeBuffer глобальные переменные $ 1, $ 2 и т. Д. Для ссылки на несовпаденияне всегда правильно устанавливается (больше?) при вызове блока.

Вот почему URI.escape (и любая другая функция, использующая gsub(), не будет работать в ActiveSupprt :: Safebuffer.

Есть несколько обсуждений по этому поводу, по-видимому, самый безопасный путь сейчас - это вызвать to_str перед передачей SafeBuffer во все, что может вызвать gsub, например, URI.encode, escape_javascriptи аналогичные функции.

Мой другой вопрос о to_s возврате того же класса - очевидно, что безопасный буфер вернет себя, а не пустую строку, это сделано специально. Чтобы получить истинную строку, .to_strможно использовать.

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

Это связано с тем, что в Rails 3 была введена концепция безопасных буферов

В Rails3 ваши представления по умолчанию защищены XSS, благодаря чему весь рендеринг можно безопасно избегать, если вы явно не указалииспользуйте помощник raw() или html_safe

0 голосов
/ 29 августа 2018

Это глупая ошибка, с которой я сейчас сталкиваюсь в Rails 5. Мой глупый обходной путь - сделать что-то вроде

ob = ActionView::OutputBuffer.new("test test")
URI.escape(ob.to_sym.to_s)

Опять же, это работает, но я все еще ищу более чистое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...