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('')