aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md26
-rw-r--r--actionview/lib/action_view/digestor.rb10
-rw-r--r--actionview/lib/action_view/helpers/form_tag_helper.rb4
-rw-r--r--actionview/test/fixtures/digestor/level/_recursion.html.erb1
-rw-r--r--actionview/test/fixtures/digestor/level/recursion.html.erb1
-rw-r--r--actionview/test/template/digestor_test.rb25
-rw-r--r--actionview/test/template/form_tag_helper_test.rb17
7 files changed, 79 insertions, 5 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 921ea2be6f..ba1c7936b3 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,3 +1,29 @@
+* Fix "Stack Level Too Deep" error when redering recursive partials.
+
+ Fixes #11340.
+
+ *Rafael Mendonça França*
+
+* Added an `enforce_utf8` hash option for `form_tag` method.
+
+ Control to output a hidden input tag with name `utf8` without monkey
+ patching.
+
+ Before:
+
+ form_tag
+ # => '<form>..<input name="utf8" type="hidden" value="&#x2713;" />..</form>'
+
+ After:
+
+ form_tag
+ # => '<form>..<input name="utf8" type="hidden" value="&#x2713;" />..</form>'
+
+ form_tag({}, { :enforce_utf8 => false })
+ # => '<form>....</form>'
+
+ *ma2gedev*
+
* Remove the deprecated `include_seconds` argument from `distance_of_time_in_words`,
pass in an `:include_seconds` hash option to use this feature.
diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb
index 9324a1ac50..a674e4d7ea 100644
--- a/actionview/lib/action_view/digestor.rb
+++ b/actionview/lib/action_view/digestor.rb
@@ -7,10 +7,14 @@ module ActionView
@@cache = ThreadSafe::Cache.new
def self.digest(name, format, finder, options = {})
- cache_key = [name, format] + Array.wrap(options[:dependencies])
- @@cache[cache_key.join('.')] ||= begin
+ cache_key = ([name, format] + Array.wrap(options[:dependencies])).join('.')
+ @@cache.fetch(cache_key) do
+ @@cache[cache_key] ||= nil if options[:partial] # Prevent re-entry
+
klass = options[:partial] || name.include?("/_") ? PartialDigestor : Digestor
- klass.new(name, format, finder, options).digest
+ digest = klass.new(name, format, finder, options).digest
+
+ @@cache[cache_key] = digest # Store the value
end
end
diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb
index 3fa7696b83..142c27ace0 100644
--- a/actionview/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/form_tag_helper.rb
@@ -38,6 +38,7 @@ module ActionView
# * A list of parameters to feed to the URL the form will be posted to.
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
# submit behavior. By default this behavior is an ajax submit.
+ # * <tt>:enforce_utf8</tt> - If set to false, a hidden input with name utf8 is not output.
#
# ==== Examples
# form_tag('/posts')
@@ -719,7 +720,8 @@ module ActionView
method_tag(method) + token_tag(authenticity_token)
end
- tags = utf8_enforcer_tag << method_tag
+ enforce_utf8 = html_options.delete("enforce_utf8") { true }
+ tags = (enforce_utf8 ? utf8_enforcer_tag : ''.html_safe) << method_tag
content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
end
diff --git a/actionview/test/fixtures/digestor/level/_recursion.html.erb b/actionview/test/fixtures/digestor/level/_recursion.html.erb
new file mode 100644
index 0000000000..ee5aaf09c3
--- /dev/null
+++ b/actionview/test/fixtures/digestor/level/_recursion.html.erb
@@ -0,0 +1 @@
+<%= render 'recursion' %>
diff --git a/actionview/test/fixtures/digestor/level/recursion.html.erb b/actionview/test/fixtures/digestor/level/recursion.html.erb
new file mode 100644
index 0000000000..ee5aaf09c3
--- /dev/null
+++ b/actionview/test/fixtures/digestor/level/recursion.html.erb
@@ -0,0 +1 @@
+<%= render 'recursion' %>
diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb
index 06735c30d3..07f8d36d93 100644
--- a/actionview/test/template/digestor_test.rb
+++ b/actionview/test/template/digestor_test.rb
@@ -95,6 +95,31 @@ class TemplateDigestorTest < ActionView::TestCase
end
end
+ def test_recursion_in_renders
+ assert digest("level/recursion") # assert recursion is possible
+ assert_not_nil digest("level/recursion") # assert digest is stored
+ end
+
+ def test_chaning_the_top_templete_on_recursion
+ assert digest("level/recursion") # assert recursion is possible
+
+ assert_digest_difference("level/recursion") do
+ change_template("level/recursion")
+ end
+
+ assert_not_nil digest("level/recursion") # assert digest is stored
+ end
+
+ def test_chaning_the_partial_templete_on_recursion
+ assert digest("level/recursion") # assert recursion is possible
+
+ assert_digest_difference("level/recursion") do
+ change_template("level/_recursion")
+ end
+
+ assert_not_nil digest("level/recursion") # assert digest is stored
+ end
+
def test_dont_generate_a_digest_for_missing_templates
assert_equal '', digest("nothing/there")
end
diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb
index 70fc6a588b..22bf438a56 100644
--- a/actionview/test/template/form_tag_helper_test.rb
+++ b/actionview/test/template/form_tag_helper_test.rb
@@ -12,9 +12,10 @@ class FormTagHelperTest < ActionView::TestCase
def hidden_fields(options = {})
method = options[:method]
+ enforce_utf8 = options.fetch(:enforce_utf8, true)
txt = %{<div style="margin:0;padding:0;display:inline">}
- txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
+ txt << %{<input name="utf8" type="hidden" value="&#x2713;" />} if enforce_utf8
if method && !%w(get post).include?(method.to_s)
txt << %{<input name="_method" type="hidden" value="#{method}" />}
end
@@ -110,6 +111,20 @@ class FormTagHelperTest < ActionView::TestCase
assert_dom_equal expected, actual
end
+ def test_form_tag_enforce_utf8_true
+ actual = form_tag({}, { :enforce_utf8 => true })
+ expected = whole_form("http://www.example.com", :enforce_utf8 => true)
+ assert_dom_equal expected, actual
+ assert actual.html_safe?
+ end
+
+ def test_form_tag_enforce_utf8_false
+ actual = form_tag({}, { :enforce_utf8 => false })
+ expected = whole_form("http://www.example.com", :enforce_utf8 => false)
+ assert_dom_equal expected, actual
+ assert actual.html_safe?
+ end
+
def test_form_tag_with_block_in_erb
output_buffer = render_erb("<%= form_tag('http://www.example.com') do %>Hello world!<% end %>")