Похоже, что html_safe
добавляет абстракцию к классу String, которая требует понимания того, что происходит, например,
<%= '1 <b>2</b>' %> # gives 1 <b>2</b> in the HTML source code
<%= h '1 <b>2</b>' %> # exactly the same as above
<%= '1 <b>2</b>'.html_safe %> # 1 <b>2</b> in HTML source code
<%= h '1 <b>2</b>'.html_safe %> # exactly the same as above
<%= h (h '1 <b>2</b>') %> # 1 <b>2</b> wont' escape twice
For строка 4, если мы говорим, хорошо, мы доверяем строке - она безопасна, но почему мы не можем ее избежать? Похоже, что для выхода h
строка должна быть небезопасной.
Итак, в строке 1, если строка не экранирована h
, он будет автоматически экранирован. В строке 5 h
не может дважды экранировать строку - другими словами, после того, как <
изменен на & lt;
, он не может экранировать его еще раз. время до & amp; lt;
.
Итак, что происходит? Сначала я подумал, что html_safe
просто добавляет к строке флаг, говоря, что это безопасно. Так почему же h
не ускользает от него? Кажется, что h
и html_escape
на самом деле взаимодействуют при использовании флага:
1) Если строка является html_safe, то h
не ускользнет от нее.
2) Если строка не html_safe, то при добавлении строки в выходной буфер она будет автоматически экранирована h
.
3) Если h
уже экранировал строку, он помечен html_safe
, поэтому повторное экранирование с помощью h
не даст никакого эффекта. (как в Строке 5, и это поведение то же самое даже в Rails 2.3.10, но в Rails 2.3.5 h
может дважды экранировать его ... поэтому в Rails 2.3.5, h
- это простой метод выхода, но где-то по пути к 2.3.10 h
стал не таким простым. Но 2.3.10 не экранирует строку автоматически, но по какой-то причине, метод html_safe
уже существует для 2.3.10 (с какой целью?))
Так оно и работает? Я думаю, что в настоящее время иногда мы не получаем то, что хотим, и сразу добавляем html_safe
в нашу переменную, что может быть довольно опасно, потому что таким образом может возникнуть XSS-атака, поэтому понимание того, как именно это работает, может быть очень важным. Вышесказанное является лишь предположением о том, как именно это работает. Может ли это быть другой механизм, и есть ли какой-нибудь документ, который его поддерживает?