raw vs. html_safe vs. h to unescape html

Ruby on-RailsErb

Ruby on-Rails Problem Overview


Suppose I have the following string

@x = "<a href='#'>Turn me into a link</a>"

In my view, I want a link to be displayed. That is, I don't want everything in @x to be unescaped and displayed as a string. What's the difference between using

<%= raw @x %>
<%= h @x %>
<%= @x.html_safe %>

?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Considering Rails 3:

html_safe actually "sets the string" as HTML Safe (it's a little more complicated than that, but it's basically it). This way, you can return HTML Safe strings from helpers or models at will.

h can only be used from within a controller or view, since it's from a helper. It will force the output to be escaped. It's not really deprecated, but you most likely won't use it anymore: the only usage is to "revert" an html_safe declaration, pretty unusual.

Prepending your expression with raw is actually equivalent to calling to_s chained with html_safe on it, but is declared on a helper, just like h, so it can only be used on controllers and views.

"SafeBuffers and Rails 3.0" is a nice explanation on how the SafeBuffers (the class that does the html_safe magic) work.

Solution 2 - Ruby on-Rails

I think it bears repeating: html_safe does not HTML-escape your string. In fact, it will prevent your string from being escaped.

<%= "<script>alert('Hello!')</script>" %>

will put:

&lt;script&gt;alert(&#x27;Hello!&#x27;)&lt;/script&gt;

into your HTML source (yay, so safe!), while:

<%= "<script>alert('Hello!')</script>".html_safe %>

will pop up the alert dialog (are you sure that's what you want?). So you probably don't want to call html_safe on any user-entered strings.

Solution 3 - Ruby on-Rails

The difference is between Rails’ html_safe() and raw(). There is an excellent post by Yehuda Katz on this, and it really boils down to this:

def raw(stringish)

  stringish.to_s.html_safe

end

Yes, raw() is a wrapper around html_safe() that forces the input to String and then calls html_safe() on it. It’s also the case that raw() is a helper in a module whereas html_safe() is a method on the String class which makes a new ActiveSupport::SafeBuffer instance — that has a @dirty flag in it.

Refer to "Rails’ html_safe vs. raw".

Solution 4 - Ruby on-Rails

  1. html_safe :

Marks a string as trusted safe. It will be inserted into HTML with no additional escaping performed.

    "<a>Hello</a>".html_safe
    #=> "<a>Hello</a>"

    nil.html_safe
    #=> NoMethodError: undefined method `html_safe' for nil:NilClass

2. raw :

raw is just a wrapper around html_safe. Use raw if there are chances that the string will be nil.

    raw("<a>Hello</a>")
    #=> "<a>Hello</a>"

    raw(nil)
    #=> ""

3. h alias for html_escape :

A utility method for escaping HTML tag characters. Use this method to escape any unsafe content.

In Rails 3 and above it is used by default so you don't need to use this method explicitly

Solution 5 - Ruby on-Rails

The best safe way is: <%= sanitize @x %>

It will avoid XSS!

Solution 6 - Ruby on-Rails

In Simple Rails terms:

h remove html tags into number characters so that rendering won't break your html

html_safe sets a boolean in string so that the string is considered as html save

raw It converts to html_safe to string

Solution 7 - Ruby on-Rails

Short and Simple

Let's assume we can't trust user input.

Bad:

user_input.html_safe # asking for trouble

Good:

user_input.html_escape # or

h(user_input) # in some view

Inputs we control:

trusted_input_only.html_safe

that should be fine. but be careful what your trusted inputs are. They must only be generated from your app.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongrauturView Question on Stackoverflow
Solution 1 - Ruby on-RailsFábio BatistaView Answer on Stackoverflow
Solution 2 - Ruby on-RailsroasmView Answer on Stackoverflow
Solution 3 - Ruby on-RailsPankhuriView Answer on Stackoverflow
Solution 4 - Ruby on-RailsDeepak MahakaleView Answer on Stackoverflow
Solution 5 - Ruby on-RailsGuilherme Y. HatanoView Answer on Stackoverflow
Solution 6 - Ruby on-Railsuser3118220View Answer on Stackoverflow
Solution 7 - Ruby on-RailsBenKoshyView Answer on Stackoverflow