Class: SandboxedErb::Template
- Inherits:
-
Object
- Object
- SandboxedErb::Template
- Defined in:
- lib/sandboxed_erb/template.rb
Overview
This class represents a template which can be compiled then run multiple times.
When declaring a template, pass an array of Mixin classes to the contructor to allow the template access to the Mixin methods.
Example module ExampleHelper
def format_date(date, format)
if format == :short_date
date.strftime("%d %b %Y %H:%M")
else
"unknown format: #{format}"
end
end
def current_time
DateTime.now
end
end
template = SandboxedErb::Template.new() #the template will now have access to the format_date() and current_time() helper function template.compile(‘the date = <%=format_date(current_time, :short_date)%>’)
Instance Method Summary collapse
-
#compile(str_template) ⇒ Object
compile the template.
-
#compile_erb_template(str_template) ⇒ Object
:nodoc:.
- #get_error ⇒ Object
-
#initialize(mixins = []) ⇒ Template
constructor
minins is an array of helper classes which expose methods to the template.
-
#run(context, locals) ⇒ Object
run a compiled template * context: A map of context objects that will be available to helper functions and instance variables, and available to sandboxed objects through the set_sandbox_context callback.
-
#sandbox_code(erb_template) ⇒ Object
:nodoc:.
Constructor Details
#initialize(mixins = []) ⇒ Template
minins is an array of helper classes which expose methods to the template
53 54 55 |
# File 'lib/sandboxed_erb/template.rb', line 53 def initialize(mixins = []) @mixins = mixins.collect { |clz| "include #{clz.name}"}.join("\n") end |
Instance Method Details
#compile(str_template) ⇒ Object
compile the template
if the template does not compile, false is returned and get_error should be called to get the compile error.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/sandboxed_erb/template.rb', line 60 def compile(str_template) erb_template = compile_erb_template(str_template) return false if erb_template.nil? #we now have a normal compile erb template (which is just ruby code) sandboxed_compiled_template = sandbox_code(erb_template) puts sandboxed_compiled_template if $DEBUG return false if sandboxed_compiled_template.nil? @clazz_name = "SandboxedErb::TClass#{self.object_id}" @file_name = "tclass_#{self.object_id}" clazz_str = <<-EOF class #{@clazz_name} < SandboxedErb::TemplateBase #{@mixins} def run_internal() #{sandboxed_compiled_template} end end #{@clazz_name}.new EOF begin @template_runner = eval(clazz_str, nil, @file_name) rescue Exception=>e @error = "Invalid code generated: #{e.}" return false end true end |
#compile_erb_template(str_template) ⇒ Object
:nodoc:
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/sandboxed_erb/template.rb', line 107 def compile_erb_template(str_template) #:nodoc: ecompiler = ERB::Compiler.new(nil) ecompiler.put_cmd = "_erbout.concat" ecompiler.insert_cmd = "_erbout.concat" cmd = [] cmd.push "_erbout = ''" ecompiler.pre_cmd = cmd cmd = [] cmd.push('_erbout') ecompiler.post_cmd = cmd e_template = ecompiler.compile(str_template) if e_template.class == Array #ruby 1.9 returns an array with the encoding prefixed as a comment on the first line... e_template = e_template[0].lines.to_a[1..-1].join end e_template end |
#get_error ⇒ Object
164 165 166 |
# File 'lib/sandboxed_erb/template.rb', line 164 def get_error @error end |
#run(context, locals) ⇒ Object
run a compiled template
-
context: A map of context objects that will be available to helper functions and instance variables, and available to sandboxed objects through the set_sandbox_context callback.
-
locals: A map of local objects that will be available to the template, and available to sandboxed objects through the set_sandbox_context callback as the :locals entry.
If the template runs successfully, the geneated content is returned. If an error occures, nil is returned and get_error should be called to get the error information.
98 99 100 101 102 103 104 105 |
# File 'lib/sandboxed_erb/template.rb', line 98 def run(context, locals) begin @template_runner.run(context, locals) rescue Exception=>e @error = e. nil end end |
#sandbox_code(erb_template) ⇒ Object
:nodoc:
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/sandboxed_erb/template.rb', line 130 def sandbox_code(erb_template) #:nodoc: @error = nil tree = nil begin tree = RubyParser.new.parse erb_template rescue Exception=>e #the message is pretty useless.. lets eval the code (it wont get executed because of the compile error) begin #extra bit of caution.. run in $SAFE=4 t = Thread.new { $SAFE = 4 eval(erb_template, nil, "line") } t.join rescue Exception=>e2 @error = e2. return nil end #if we got here then somehow code that would not compile using RubyParser eval'ed ok... throw "SYSTEM ERROR: you may be owned! Code that should not be able to compile has run!" end begin context = PartialRuby::PureRubyContext.new tree_processor = SandboxedErb::TreeProcessor.new() tree = tree_processor.process(tree) emulationcode = context.emul tree rescue Exception=>e @error = e. return nil end emulationcode end |