Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

changes to integrate safemode with rails 2.3.5

  • Loading branch information...
commit f22595fc85af636b2fd851edc109ced2d27bc351 1 parent f560762
Matthias Viehweger and Raphaela Wrede authored
View
2  init.rb
@@ -1,3 +1 @@
require 'safemode'
-
-require 'action_view/conditional_template_handler' if Object.const_defined?('ActionView')
View
40 lib/action_view/conditional_template_handler.rb
@@ -1,40 +0,0 @@
-module ActionView
- class Template
- def initialize(view, path, use_full_path = true, locals = {})
- @view = view
- @finder = @view.finder
-
- # Clear the forward slash at the beginning if exists
- @path = use_full_path ? path.sub(/^\//, '') : path
- @view.first_render ||= @path
- @source = nil # Don't read the source until we know that it is required
- set_extension_and_file_name(use_full_path)
-
- @locals = locals || {}
- @handler = self.class.handler_class_for_template(self).new(@view)
- end
-
- def self.register_template_handler(extension, klass, options = {})
- @@template_handlers[extension.to_sym] = options.update(:class => klass)
- ActionView::TemplateFinder.update_extension_cache_for(extension.to_s)
- end
-
- def self.handler_class_for_template(template)
- if template.extension && handler = @@template_handlers[template.extension.to_sym]
- if handler.is_a? Hash
- return handler[:class] if eval_handler_conditions(template, handler)
- else
- return handler
- end
- end
- @@default_template_handlers
- end
-
- def self.eval_handler_conditions(template, handler)
- [:path, :filename].each do |type|
- return false if handler[type] and handler[type] !~ template.send(type)
- end
- true
- end
- end
-end
View
20 lib/action_view/template_handlers/safe_erb.rb
@@ -6,7 +6,7 @@ module TemplateHandlers
class SafeErb < TemplateHandler
include Compilable rescue nil # does not exist prior Rails 2.1
extend SafemodeHandler
-
+
def self.line_offset
0
end
@@ -16,18 +16,24 @@ def compile(template)
# template instance
src = template.respond_to?(:source) ? template.source : template
filename = template.filename rescue nil
-
- code = ::ERB.new(src, nil, @view.erb_trim_mode).src
+ erb_trim_mode = '-'
+
+ # code = ::ERB.new(src, nil, @view.erb_trim_mode).src
+ code = ::ERB.new("<% __in_erb_template=true %>#{src}", nil, erb_trim_mode, '@output_buffer').src
+ # Ruby 1.9 prepends an encoding to the source. However this is
+ # useless because you can only set an encoding on the first line
+ RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
+
code.gsub!('\\','\\\\\\') # backslashes would disappear in compile_template/modul_eval, so we escape them
-
- code = <<-CODE
+
+ code = <<-CODE
handler = ActionView::TemplateHandlers::SafeHaml
assigns = handler.valid_assigns(@template.assigns)
methods = handler.delegate_methods(self)
code = %Q(#{code});
-
+
box = Safemode::Box.new(self, methods, #{filename.inspect}, 0)
- box.eval(code, assigns, local_assigns, &lambda{ yield })
+ box.eval(code, assigns, local_assigns, &lambda{ yield })
CODE
puts code
code
View
38 lib/safemode/parser.rb
@@ -58,15 +58,25 @@ def process_vcall(exp)
exp.clear
"to_jail.#{name}"
end
-
+
+ def process_iasgn(exp)
+ code = super
+ if code != '@output_buffer = ""'
+ raise_security_error(:iasgn, code)
+ else
+ code
+ end
+ end
+
# see http://www.namikilab.tuat.ac.jp/~sasada/prog/rubynodes/nodes.html
-
- allowed = [ :call, :vcall, :evstr,
- :lvar, :dvar, :ivar, :lasgn, :masgn, :dasgn, :dasgn_curr,
- :lit, :str, :dstr, :dsym, :nil, :true, :false,
- :array, :zarray, :hash, :dot2, :dot3, :flip2, :flip3,
- :if, :case, :when, :while, :until, :iter, :for, :break, :next, :yield,
+
+ allowed = [ :call, :vcall, :evstr,
+ :lvar, :dvar, :ivar, :lasgn, :masgn, :dasgn, :dasgn_curr,
+ :lit, :str, :dstr, :dsym, :nil, :true, :false,
+ :array, :zarray, :hash, :dot2, :dot3, :flip2, :flip3,
+ :if, :case, :when, :while, :until, :iter, :for, :break, :next, :yield,
:and, :or, :not,
+ :iasgn, # iasgn is sometimes allowed
# not sure about self ...
:self,
# unnecessarily advanced?
@@ -74,16 +84,16 @@ def process_vcall(exp)
:op_asgn1, :op_asgn2, :op_asgn_and, :op_asgn_or,
# needed for haml
:block ]
-
+
disallowed = [ # :self, # self doesn't seem to be needed for vcalls?
:const, :defn, :defs, :alias, :valias, :undef, :class, :attrset,
- :module, :sclass, :colon2, :colon3,
- :fbody, :scope, :args, :block_arg, :postexe,
- :redo, :retry, :begin, :rescue, :resbody, :ensure,
+ :module, :sclass, :colon2, :colon3,
+ :fbody, :scope, :args, :block_arg, :postexe,
+ :redo, :retry, :begin, :rescue, :resbody, :ensure,
:defined, :super, :zsuper, :return,
- :dmethod, :bmethod, :to_ary, :svalue, :match,
- :iasgn, :attrasgn, :cdecl, :cvasgn, :cvdecl, :cvar, :gvar, :gasgn,
- :xstr, :dxstr,
+ :dmethod, :bmethod, :to_ary, :svalue, :match,
+ :attrasgn, :cdecl, :cvasgn, :cvdecl, :cvar, :gvar, :gasgn,
+ :xstr, :dxstr,
# not sure how secure ruby regexp is, so leave it out for now
:dregx, :dregx_once, :match2, :match3, :nth_ref, :back_ref ]
View
8 test/test_safemode_parser.rb
@@ -25,7 +25,13 @@ def test_ternary_should_be_usable_for_erb
assert_jailed "if true then\n 1\n else\n2\nend", "true ? 1 : 2"
end
-private
+ def test_output_buffer_should_be_assignable
+ assert_nothing_raised do
+ jail('@output_buffer = ""')
+ end
+ end
+
+private
def assert_jailed(expected, code)
assert_equal expected.gsub(' ', ''), jail(code).gsub(' ', '')
Please sign in to comment.
Something went wrong with that request. Please try again.