diff --git a/CHANGELOG b/CHANGELOG
index 538e2c4c1..a5f35229e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,8 @@
=== Edge
+* Prevent recursion via the tag. [Sean Cribbs]
+* Update Highline. [Sean Cribbs]
* Update Cucumber and RSpec, clean up some features and fix specs. [Sean Cribbs]
* Set the protected attributes for users in User.protected_attributes
[Jim Gay]
diff --git a/app/models/standard_tags.rb b/app/models/standard_tags.rb
index 4f51f53c0..c61190bd4 100644
--- a/app/models/standard_tags.rb
+++ b/app/models/standard_tags.rb
@@ -347,6 +347,13 @@ class TagError < StandardError; end
tag 'content' do |tag|
page = tag.locals.page
part_name = tag_part_name(tag)
+ # Prevent simple and deep recursive rendering of the same page part
+ rendered_parts = (tag.locals.rendered_parts ||= Hash.new {|h,k| h[k] = []})
+ if rendered_parts[page.id].include?(part_name)
+ raise TagError.new(%{Recursion error: already rendering the `#{part_name}' part.})
+ else
+ rendered_parts[page.id] << part_name
+ end
boolean_attr = proc do |attribute_name, default|
attribute = (tag.attr[attribute_name] || default).to_s
raise TagError.new(%{`#{attribute_name}' attribute of `content' tag must be set to either "true" or "false"}) unless attribute =~ /true|false/i
diff --git a/spec/datasets/pages_dataset.rb b/spec/datasets/pages_dataset.rb
index cf88c479b..4c2569ff0 100644
--- a/spec/datasets/pages_dataset.rb
+++ b/spec/datasets/pages_dataset.rb
@@ -51,6 +51,11 @@ def load
create_page_part "games"
create_page "Guests"
end
+ create_page "Recursive parts" do
+ create_page_part "recursive_body", :name => "body", :content => ""
+ create_page_part "recursive_one", :name => "one", :content => ''
+ create_page_part "recursive_two", :name => "two", :content => ''
+ end
end
end
\ No newline at end of file
diff --git a/spec/models/standard_tags_spec.rb b/spec/models/standard_tags_spec.rb
index dd3163bae..6ff8bc986 100644
--- a/spec/models/standard_tags_spec.rb
+++ b/spec/models/standard_tags_spec.rb
@@ -253,6 +253,15 @@
page(:home).should render('').as("Just a test.")
end
+ it "should prevent simple recursion" do
+ page(:recursive_parts).should render('').with_error("Recursion error: already rendering the `body' part.")
+ end
+
+ it "should prevent deep recursion" do
+ page(:recursive_parts).should render('').with_error("Recursion error: already rendering the `one' part.")
+ page(:recursive_parts).should render('').with_error("Recursion error: already rendering the `two' part.")
+ end
+
describe "with inherit attribute" do
it "missing or set to 'false' should render the current page's part" do
page.should render('').as('')