HTML-safe, ActiveSupport::SafeBuffer explained

  • Rails 3 introduced the ActiveSupport::SafeBuffer module to add an HTML-safe flag to strings. It’s false by default, especially when the string comes from an external source like params or the database. You can return the flag with “string”.html_safe?.
  • The HTML-escape method h(), well, escapes the string and marks a string HTML-safe.
    h("html>").html_safe? #=> true 
    ("html>").html_safe? #=> false
  • The Erb notation <%= “string” %> inspects the HTML-safe flag of the string. If it’s false it will escape the string automatically, otherwise it won’t.
  • There’s a method called #html_safe, that marks a string HTML-safe. It’s a common misconception that this method makes the string safe, it doesn’t. If you know that the string is safe, you can call this method, but it will only set the HTML-safe flag. So you should never do <%= params[:user_input].html_safe %>. Use the h() method to make it really HTML-safe by escaping it.
  • The raw() method is similar to the html_safe method. So you should never do: <%= raw params[:user_input] %>
  • This is how the string concatenation methods (+, concat(), <<) work:
    • If the left side is HTML-unsafe or the right side is HTML-safe, then it works like normal string concatenation and keeps the HTML-safe flag of the left side
    • Otherwise it will HTML-escape the right side and add it to the string