Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

More intelligent way to html_escape labels and hints (GH-299)

This commit won't escape html entities in strings marked as html_safe according to newer rails versions.
Additionally you can now turn html escaping off by setting

Formtastic::SemanticFormBuilder.escape_html_entities_in_hints_and_labels = false
  • Loading branch information...
commit 2d2d8131016d560807940fad2720f187d9b16f67 1 parent 364ae5c
Morton Jonuschat yabawock authored
Showing with 34 additions and 6 deletions.
  1. +4 −0 README.textile
  2. +14 −5 lib/formtastic.rb
  3. +16 −1 spec/label_spec.rb
4 README.textile
View
@@ -517,7 +517,11 @@ If you want to add your own input types to encapsulate your own logic or interfa
@Formtastic::SemanticFormHelper.builder = MyCustomBuilder@
+h2. Security
+By default formtastic escapes html entities in both labels and hints unless a string is marked as html_safe. If you are using an older rails version which doesn't know html_safe, or you want to globally turn this feature off, you can set the following in your initializer:
+
+Formtastic::SemanticFormBuilder.escape_html_entities_in_hints_and_labels = false
h2. Status
19 lib/formtastic.rb
View
@@ -19,11 +19,12 @@ class SemanticFormBuilder < ActionView::Helpers::FormBuilder
@@file_methods = [ :file?, :public_filename, :filename ]
@@priority_countries = ["Australia", "Canada", "United Kingdom", "United States"]
@@i18n_lookups_by_default = false
+ @@escape_html_entities_in_hints_and_labels = true
@@default_commit_button_accesskey = nil
cattr_accessor :default_text_field_size, :default_text_area_height, :all_fields_required_by_default, :include_blank_for_select_by_default,
:required_string, :optional_string, :inline_errors, :label_str_method, :collection_label_methods,
- :inline_order, :file_methods, :priority_countries, :i18n_lookups_by_default, :default_commit_button_accesskey
+ :inline_order, :file_methods, :priority_countries, :i18n_lookups_by_default, :escape_html_entities_in_hints_and_labels, :default_commit_button_accesskey
RESERVED_COLUMNS = [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
@@ -878,7 +879,7 @@ def radio_input(method, options)
html_options[:checked] = selected_value == value if selected_option_is_present
li_content = template.content_tag(:label,
- Formtastic::Util.html_safe("#{self.radio_button(input_name, value, html_options)} #{template.escape_once(label)}"),
+ Formtastic::Util.html_safe("#{self.radio_button(input_name, value, html_options)} #{escape_html_entities(label)}"),
:for => input_id
)
@@ -1149,7 +1150,7 @@ def check_boxes_input(method, options)
html_options[:id] = input_id
li_content = template.content_tag(:label,
- Formtastic::Util.html_safe("#{self.check_box(input_name, html_options, value, unchecked_value)} #{template.escape_once(label)}"),
+ Formtastic::Util.html_safe("#{self.check_box(input_name, html_options, value, unchecked_value)} #{escape_html_entities(label)}"),
:for => input_id
)
@@ -1622,7 +1623,7 @@ def localized_string(key, value, type, options = {}) #:nodoc:
key = value if value.is_a?(::Symbol)
if value.is_a?(::String)
- template.escape_once(value)
+ escape_html_entities(value)
else
use_i18n = value.nil? ? @@i18n_lookups_by_default : (value != false)
@@ -1644,7 +1645,7 @@ def localized_string(key, value, type, options = {}) #:nodoc:
i18n_value = ::Formtastic::I18n.t(defaults.shift,
options.merge(:default => defaults, :scope => type.to_s.pluralize.to_sym))
- i18n_value = template.escape_once(i18n_value) if i18n_value.is_a?(::String)
+ i18n_value = escape_html_entities(i18n_value) if i18n_value.is_a?(::String)
i18n_value.blank? ? nil : i18n_value
end
end
@@ -1677,6 +1678,14 @@ def set_include_blank(options)
options
end
+ def escape_html_entities(string) #:nodoc:
+ if @@escape_html_entities_in_hints_and_labels
+ # Acceppt html_safe flag as indicator to skip escaping
+ string = template.escape_once(string) unless string.respond_to?(:html_safe?) && string.html_safe? == true
+ end
+ string
+ end
+
end
# Wrappers around form_for (etc) with :builder => SemanticFormBuilder.
17 spec/label_spec.rb
View
@@ -43,11 +43,26 @@
end
end
- it 'should html escape the label string' do
+ it 'should html escape the label string by default' do
semantic_form_for(@new_post) do |builder|
builder.label(:login, :required => false, :label => '<b>My label</b>').should == "<label for=\"post_login\">&lt;b&gt;My label&lt;/b&gt;</label>"
end
end
+
+ it 'should not html escape the label if configured that way' do
+ ::Formtastic::SemanticFormBuilder.escape_html_entities_in_hints_and_labels = false
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login, :required => false, :label => '<b>My label</b>').should == "<label for=\"post_login\"><b>My label</b></label>"
+ end
+ end
+
+ it 'should not html escape the label string for html_safe strings' do
+ ::Formtastic::SemanticFormBuilder.escape_html_entities_in_hints_and_labels = true
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login, :required => false, :label => '<b>My label</b>'.html_safe).should == "<label for=\"post_login\"><b>My label</b></label>"
+ end
+ end
+
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.