Navigation Menu

Skip to content

Commit

Permalink
updated to use latest version of ruby_parser, ruby2ruby, and sexp_pro…
Browse files Browse the repository at this point in the history
…cessor
  • Loading branch information
dmitri-d committed Nov 12, 2012
1 parent dc6b1b0 commit 1e5370a
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 57 deletions.
11 changes: 7 additions & 4 deletions Gemfile
@@ -1,15 +1,18 @@
source "http://rubygems.org"

gem "ruby2ruby"
gem "ruby_parser"
gem 'sexp_processor', ">= 4.1.2"
gem 'ruby2ruby', ">= 2.0.1"
gem "ruby_parser", ">= 3.0.1"

# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.
group :development do
gem "shoulda", ">= 0"
gem "rdoc", "~> 3.12"
gem "bundler", "~> 1.0.0"
gem "bundler", "~> 1.0"
gem "jeweler", "~> 1.8.3"
gem "rcov", ">= 0"
gem "rcov", :platforms => :ruby_18
gem "simplecov", :platforms => :ruby_19
gem "test-unit", :platforms => :ruby_19
gem "rake"
end
46 changes: 30 additions & 16 deletions Gemfile.lock
@@ -1,38 +1,52 @@
GEM
remote: http://rubygems.org/
specs:
activesupport (3.2.8)
i18n (~> 0.6)
multi_json (~> 1.0)
git (1.2.5)
jeweler (1.8.3)
i18n (0.6.1)
jeweler (1.8.4)
bundler (~> 1.0)
git (>= 1.2.5)
rake
rdoc
json (1.6.5)
json (1.7.5)
multi_json (1.3.6)
rake (0.9.2.2)
rcov (1.0.0)
rdoc (3.12)
json (~> 1.4)
ruby2ruby (1.3.1)
ruby_parser (~> 2.0)
sexp_processor (~> 3.0)
ruby_parser (2.3.1)
sexp_processor (~> 3.0)
sexp_processor (3.1.0)
shoulda (3.0.1)
shoulda-context (~> 1.0.0)
shoulda-matchers (~> 1.0.0)
shoulda-context (1.0.0)
shoulda-matchers (1.0.0)
ruby2ruby (2.0.1)
ruby_parser (~> 3.0.0)
sexp_processor (~> 4.0)
ruby_parser (3.0.1)
sexp_processor (~> 4.1)
sexp_processor (4.1.2)
shoulda (3.3.2)
shoulda-context (~> 1.0.1)
shoulda-matchers (~> 1.4.1)
shoulda-context (1.0.1)
shoulda-matchers (1.4.1)
activesupport (>= 3.0.0)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
test-unit (2.5.2)

PLATFORMS
ruby

DEPENDENCIES
bundler (~> 1.0.0)
bundler (~> 1.0)
jeweler (~> 1.8.3)
rake
rcov
rdoc (~> 3.12)
ruby2ruby
ruby_parser
ruby2ruby (>= 2.0.1)
ruby_parser (>= 3.0.1)
sexp_processor (>= 4.1.2)
shoulda
simplecov
test-unit
20 changes: 14 additions & 6 deletions Rakefile
Expand Up @@ -46,12 +46,20 @@ Rake::TestTask.new(:test) do |test|
test.verbose = true
end

require 'rcov/rcovtask'
Rcov::RcovTask.new do |test|
test.libs << 'test'
test.pattern = 'test/**/test_*.rb'
test.verbose = true
test.rcov_opts << '--exclude "gems/*"'
if RUBY_VERSION >= "1.9"
desc "Generate coverage report for tests"
task :coverage do |cov|
ENV['COVERAGE'] = 'true'
Rake::Task[:test].execute
end
else
require 'rcov/rcovtask'
Rcov::RcovTask.new do |test|
test.libs << 'test'
test.pattern = 'test/**/test_*.rb'
test.verbose = true
test.rcov_opts << '--exclude "gems/*"'
end
end

task :default => :test
Expand Down
4 changes: 2 additions & 2 deletions lib/safemode/blankslate.rb
Expand Up @@ -3,9 +3,9 @@ class Blankslate
@@allow_instance_methods = ['class', 'inspect', 'methods', 'respond_to?', 'to_s', 'instance_variable_get']
@@allow_class_methods = ['methods', 'new', 'name', 'inspect', '<', 'ancestors', '=='] # < needed in Rails Object#subclasses_of

silently { undef_methods(*instance_methods - @@allow_instance_methods) }
silently { undef_methods(*instance_methods.map(&:to_s) - @@allow_instance_methods) }
class << self
silently { undef_methods(*instance_methods - @@allow_class_methods) }
silently { undef_methods(*instance_methods.map(&:to_s) - @@allow_class_methods) }

def method_added(name) end # ActiveSupport needs this

Expand Down
4 changes: 2 additions & 2 deletions lib/safemode/core_jails.rb
Expand Up @@ -22,7 +22,7 @@ def core_classes
end

def core_jail_methods(klass)
@@methods_whitelist[klass.name] + (@@default_methods & klass.instance_methods)
@@methods_whitelist[klass.name] + (@@default_methods & klass.instance_methods.map(&:to_s))
end
end

Expand Down Expand Up @@ -67,7 +67,7 @@ def core_jail_methods(klass)

'String' => %w(blank? capitalize capitalize! casecmp center chomp chomp!
chop chop! concat count crypt delete delete! downcase
downcase! dump each each_byte each_line empty? end_with? gsub
downcase! dump each_byte each_line empty? end_with? force_encoding gsub
gsub! hash hex include? index insert intern iseuc issjis
isutf8 kconv length ljust lstrip lstrip! match next next! oct
reverse reverse! rindex rjust rstrip rstrip! scan size slice
Expand Down
37 changes: 25 additions & 12 deletions lib/safemode/parser.rb
Expand Up @@ -36,7 +36,7 @@ def process_call(exp)
receiver = jail process_call_receiver(exp)
name = exp.shift
args = process_call_args(exp)
process_call_code(receiver, name, args)
process_call_code(receiver, name, args)
end

def process_fcall(exp)
Expand Down Expand Up @@ -79,16 +79,19 @@ def process_iasgn(exp)
:iasgn, # iasgn is sometimes allowed
# not sure about self ...
:self,
# :args is now used for block parameters
:args,
# unnecessarily advanced?
:argscat, :argspush, :splat, :block_pass,
: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,
# see below for :const handling
:defn, :defs, :alias, :valias, :undef, :class, :attrset,
:module, :sclass, :colon2, :colon3,
:fbody, :scope, :args, :block_arg, :postexe,
:fbody, :scope, :block_arg, :postexe,
:redo, :retry, :begin, :rescue, :resbody, :ensure,
:defined, :super, :zsuper, :return,
:dmethod, :bmethod, :to_ary, :svalue, :match,
Expand All @@ -102,11 +105,18 @@ def process_iasgn(exp)
# :ifunc, :method, :last, :opt_n, :cfunc, :newline, :alloca, :memo, :cref

disallowed.each do |name|
define_method "process_#{name}" do
code = super
define_method "process_#{name}" do |arg|
code = super(arg)
raise_security_error(name, code)
end
end

# handling of Encoding constants in ruby 1.9.
# Note: ruby_parser evaluates __ENCODING__ to :const Encoding::UTF_8
def process_const(arg)
raise_security_error("constant", super(arg)) unless (RUBY_VERSION >= "1.9" and arg.sexp_type.class == Encoding)
"Encoding::#{super(arg).gsub('-', '_')}"
end

def raise_security_error(type, info)
raise Safemode::SecurityError.new(type, info)
Expand All @@ -124,14 +134,17 @@ def process_call_receiver(exp)
end

def process_call_args(exp)
args_exp = exp.shift rescue nil
if args_exp && args_exp.first == :array # FIX
args = "#{process(args_exp)[1..-2]}"
else
args = process args_exp
args = nil if args.empty?
args = []
while not exp.empty? do
args_exp = exp.shift
if args_exp && args_exp.first == :array # FIX
processed = "#{process(args_exp)[1..-2]}"
else
processed = process args_exp
end
args << processed unless (processed.nil? or processed.empty?)
end
args
args.empty? ? nil : args.join(", ")
end

def process_call_code(receiver, name, args)
Expand Down
6 changes: 3 additions & 3 deletions lib/safemode/scope.rb
Expand Up @@ -29,10 +29,10 @@ def print(*args)
def output
@_safemode_output
end

def method_missing(method, *args, &block)
if @locals.has_key?(method)
@locals[method]
@locals[method]
elsif @delegate_methods.include?(method)
@delegate.send method, *unjail_args(args), &block
else
Expand All @@ -54,5 +54,5 @@ def unjail_args(args)
arg.class.name =~ /::Jail$/ ? arg.instance_variable_get(:@source) : arg
end
end
end
end
end
19 changes: 11 additions & 8 deletions safemode.gemspec
Expand Up @@ -5,11 +5,11 @@

Gem::Specification.new do |s|
s.name = "safemode"
s.version = "1.0.1"
s.version = "1.0.2"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Sven Fuchs", "Peter Cooper", "Matthias Viehweger", "Kingsley Hendrickse", "Ohad Levy"]
s.date = "2012-03-16"
s.date = "2012-10-24"
s.description = "A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby. Provides Rails ActionView template handlers for ERB and Haml."
s.email = "ohadlevy@gmail.com"
s.extra_rdoc_files = [
Expand Down Expand Up @@ -56,31 +56,34 @@ Gem::Specification.new do |s|
s.specification_version = 3

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<ruby2ruby>, [">= 0"])
s.add_runtime_dependency(%q<ruby_parser>, [">= 0"])
s.add_runtime_dependency(%q<ruby2ruby>, [">= 2.0.0.b1"])
s.add_runtime_dependency(%q<ruby_parser>, [">= 3.0.0.a9"])
s.add_development_dependency(%q<shoulda>, [">= 0"])
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
s.add_development_dependency(%q<rcov>, [">= 0"])
s.add_development_dependency(%q<simplecov>, [">= 0"])
s.add_development_dependency(%q<rake>, [">= 0"])
else
s.add_dependency(%q<ruby2ruby>, [">= 0"])
s.add_dependency(%q<ruby_parser>, [">= 0"])
s.add_dependency(%q<ruby2ruby>, [">= 2.0.0.b1"])
s.add_dependency(%q<ruby_parser>, [">= 3.0.0.a9"])
s.add_dependency(%q<shoulda>, [">= 0"])
s.add_dependency(%q<rdoc>, ["~> 3.12"])
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
s.add_dependency(%q<simplecov>, [">= 0"])
s.add_dependency(%q<rcov>, [">= 0"])
s.add_dependency(%q<rake>, [">= 0"])
end
else
s.add_dependency(%q<ruby2ruby>, [">= 0"])
s.add_dependency(%q<ruby_parser>, [">= 0"])
s.add_dependency(%q<ruby2ruby>, [">= 2.0.0.b1"])
s.add_dependency(%q<ruby_parser>, [">= 3.0.0.a9"])
s.add_dependency(%q<shoulda>, [">= 0"])
s.add_dependency(%q<rdoc>, ["~> 3.12"])
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
s.add_dependency(%q<simplecov>, [">= 0"])
s.add_dependency(%q<rcov>, [">= 0"])
s.add_dependency(%q<rake>, [">= 0"])
end
Expand Down
2 changes: 1 addition & 1 deletion test/test_erb_eval.rb
Expand Up @@ -73,4 +73,4 @@ def test_calling_#{call.gsub(/[\W]/, '_')}_should_raise_security
)
end

end
end
9 changes: 9 additions & 0 deletions test/test_helper.rb
@@ -1,3 +1,8 @@
if RUBY_VERSION >= '1.9'and ENV['COVERAGE']
require 'simplecov'
SimpleCov.start {add_filter 'test_'}
end

$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')

require 'rubygems'
Expand Down Expand Up @@ -96,6 +101,10 @@ def to_jail
def comments
[Comment.new(self), Comment.new(self)]
end

def method_missing(method, *args, &block)
super(method, *args, &block)
end
end

class Comment
Expand Down
4 changes: 2 additions & 2 deletions test/test_jail.rb
Expand Up @@ -21,7 +21,7 @@ def test_sending_to_jail_to_an_object_should_return_a_jail
def test_jail_instances_should_have_limited_methods
expected = ["class", "inspect", "method_missing", "methods", "respond_to?", "to_jail", "to_s", "instance_variable_get"]
objects.each do |object|
assert_equal expected.sort, reject_pretty_methods(object.to_jail.methods.sort)
assert_equal expected.sort, reject_pretty_methods(object.to_jail.methods.map(&:to_s).sort)
end
end

Expand All @@ -32,7 +32,7 @@ def test_jail_classes_should_have_limited_methods
"ancestors", "==" # ancestors and == needed in Rails::Generator::Spec#lookup_class
]
objects.each do |object|
assert_equal expected.sort, reject_pretty_methods(object.to_jail.class.methods.sort)
assert_equal expected.sort, reject_pretty_methods(object.to_jail.class.methods.map(&:to_s).sort)
end
end

Expand Down
2 changes: 1 addition & 1 deletion test/test_safemode_eval.rb
Expand Up @@ -28,7 +28,7 @@ def test_should_allow_method_access_on_assigns
end

def test_should_allow_method_access_on_locals
assert_nothing_raised{ @box.eval "article.title", {}, @locals }
assert_nothing_raised{ @box.eval("article.title", {}, @locals) }
end

def test_should_not_raise_on_if_using_return_values
Expand Down

0 comments on commit 1e5370a

Please sign in to comment.