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.
This commit is contained in:
Jacques Distler 2008-12-21 02:47:45 -06:00
parent dcd3e63ae8
commit 91eb8f5fbf

View file

@ -10,38 +10,41 @@ require 'chunks/wiki'
class Include < WikiChunk::WikiReference class Include < WikiChunk::WikiReference
INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]+?)\s*\]\]/i INCLUDE_PATTERN = /\[\[!include\s+([^\]\s][^\]]+?)\s*\]\]/i
@@included_by = []
def self.pattern() INCLUDE_PATTERN end def self.pattern() INCLUDE_PATTERN end
def initialize(match_data, content) def initialize(match_data, content)
super super
@page_name = match_data[1].strip @page_name = match_data[1].strip
rendering_mode = content.options[:mode] || :show rendering_mode = content.options[:mode] || :show
@@included_by.push(@content.page_name)
@unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode) @unmask_text = get_unmask_text_avoiding_recursion_loops(rendering_mode)
end end
private private
def get_unmask_text_avoiding_recursion_loops(rendering_mode) 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 "<em>Recursive include detected: #{@content.page_name} &#x2192; #{@content.page_name}</em>\n"
end
# TODO This way of instantiating a renderer is ugly. # TODO This way of instantiating a renderer is ugly.
renderer = PageRenderer.new(refpage.current_revision) renderer = PageRenderer.new(refpage.current_revision)
if renderer.wiki_includes.include?(@content.page_name) included_content =
# this will break the recursion case rendering_mode
@content.delete_chunk(self)
return "<em>Recursive include detected; #{@page_name} --> #{@content.page_name} " +
"--> #{@page_name}</em>\n"
else
included_content =
case rendering_mode
when :show then renderer.display_content when :show then renderer.display_content
when :publish then renderer.display_published when :publish then renderer.display_published
when :export then renderer.display_content_for_export when :export then renderer.display_content_for_export
else raise "Unsupported rendering mode #{@mode.inspect}" else
end raise "Unsupported rendering mode #{@mode.inspect}"
@content.merge_chunks(included_content) end
return included_content.pre_rendered @content.merge_chunks(included_content)
end @@included_by = []
return included_content.pre_rendered
else else
@@included_by = []
return "<em>Could not include #{@page_name}</em>\n" return "<em>Could not include #{@page_name}</em>\n"
end end
end end