Permalink
Browse files

Fix "Stack Level Too Deep" error when rendering recursive partials

When rendering recursive partial Action View is trying to generate the
view digest infinitly causing a stack level error.

Fixes #11340
  • Loading branch information...
1 parent 0fa04e5 commit 247aa53fdd7efccebe691b0f6dce9b2195a13bf3 @rafaelfranca rafaelfranca committed Jul 7, 2013
View
@@ -1,5 +1,11 @@
## unreleased ##
+* Fix "Stack Level Too Deep" error when redering recursive partials.
+
+ Fixes #11340.
+
+ *Rafael Mendonça França*
+
* Pick `DateField` `DateTimeField` and `ColorField` values from stringified options allowing use of symbol keys with helpers.
*Jon Rowe*
@@ -7,10 +7,14 @@ class Digestor
@@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
@@ -0,0 +1 @@
+<%= render 'recursion' %>
@@ -0,0 +1 @@
+<%= render 'recursion' %>
@@ -95,6 +95,31 @@ def test_nested_template_directory
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

0 comments on commit 247aa53

Please sign in to comment.