From 91eb8f5fbf40dc8b999cfd1131bb468ca0bfba58 Mon Sep 17 00:00:00 2001 From: Jacques Distler Date: Sun, 21 Dec 2008 02:47:45 -0600 Subject: [PATCH] Fix Recursive Includes Another very amusing 3-year old bug from the main Instiki Bug Tracker (don't they ever fix anything?): the chunk-handling code was supposed to prevent recursive [[!include ...]] statements. Alas, instead of actually preventing them it would -- when it encountered a recursive include -- churn away until Rails ran out of stack space. Fixed. --- lib/chunks/include.rb | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/chunks/include.rb b/lib/chunks/include.rb index 47c3f273..3a64946c 100644 --- a/lib/chunks/include.rb +++ b/lib/chunks/include.rb @@ -10,38 +10,41 @@ require 'chunks/wiki' class Include < WikiChunk::WikiReference INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]+?)\s*\]\]/i + @@included_by = [] def self.pattern() INCLUDE_PATTERN end def initialize(match_data, content) super @page_name = match_data[1].strip rendering_mode = content.options[:mode] || :show + @@included_by.push(@content.page_name) @unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode) end private def get_unmask_text_avoiding_recursion_loops(rendering_mode) - if refpage + if refpage + if @@included_by.include?(refpage.page.name) + @content.delete_chunk(self) + @@included_by = [] + return "Recursive include detected: #{@content.page_name} → #{@content.page_name}\n" + end # TODO This way of instantiating a renderer is ugly. renderer = PageRenderer.new(refpage.current_revision) - if renderer.wiki_includes.include?(@content.page_name) - # this will break the recursion - @content.delete_chunk(self) - return "Recursive include detected; #{@page_name} --> #{@content.page_name} " + - "--> #{@page_name}\n" - else - included_content = - case rendering_mode + included_content = + case rendering_mode when :show then renderer.display_content when :publish then renderer.display_published when :export then renderer.display_content_for_export - else raise "Unsupported rendering mode #{@mode.inspect}" - end - @content.merge_chunks(included_content) - return included_content.pre_rendered - end + else + raise "Unsupported rendering mode #{@mode.inspect}" + end + @content.merge_chunks(included_content) + @@included_by = [] + return included_content.pre_rendered else + @@included_by = [] return "Could not include #{@page_name}\n" end end