safemode 1.3.4 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +11 -11
- data/{LICENCSE → LICENSE} +0 -0
- data/README.markdown +7 -5
- data/Rakefile +6 -15
- data/VERSION +1 -1
- data/lib/action_view/template_handlers/safe_erb.rb +2 -2
- data/lib/safemode/blankslate.rb +1 -1
- data/lib/safemode/core_jails.rb +5 -5
- data/lib/safemode/jail.rb +6 -11
- data/lib/safemode/parser.rb +2 -2
- data/safemode.gemspec +39 -45
- data/test/test_helper.rb +34 -19
- data/test/test_jail.rb +12 -3
- data/test/test_safemode_eval.rb +15 -19
- metadata +23 -52
- data/.travis.yml +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9bdba4c6031653f1249ce8730385b47d60e917bd089809dfb405612c9a5200d4
|
4
|
+
data.tar.gz: a36f91fec355baf6e0f89c8354f538cfeea2fa6f2838ba6de1416f51d832af9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20b1b1ef4ab2a9b8ac59d281688e118d264bc96f2b2fe0dec48aa3b4ce0c4fdcf0e1612d47a958f0434e5f155219372dc485b32be807bf7b40593ff2a1bc198e
|
7
|
+
data.tar.gz: 33c6602e612d265c4fb227de48ac6f204eb6d473bf35027b181335227584331a80b6fb57e424e5d7c658e3179296505c6800aa0a3a294f33a0e4efc44ac5518a
|
data/Gemfile
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
gem
|
3
|
+
source 'http://rubygems.org'
|
4
|
+
|
5
|
+
gem 'ruby2ruby', '>= 2.4.0'
|
6
|
+
gem 'ruby_parser', '>= 3.10.1'
|
7
|
+
gem 'sexp_processor', '>= 4.10.0'
|
6
8
|
|
7
9
|
# Add dependencies to develop your gem here.
|
8
10
|
# Include everything needed to run rake, tests, features, etc.
|
9
11
|
group :development do
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
gem
|
13
|
-
gem
|
14
|
-
gem
|
15
|
-
gem "test-unit", :platforms => [:ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24, :jruby]
|
16
|
-
gem "rake", RUBY_VERSION.start_with?("1.8") ? "< 11" : ">= 0"
|
12
|
+
gem 'jeweler'
|
13
|
+
gem 'rake'
|
14
|
+
gem 'rdoc', '~> 3.12'
|
15
|
+
gem 'simplecov'
|
16
|
+
gem 'test-unit'
|
17
17
|
end
|
data/{LICENCSE → LICENSE}
RENAMED
File without changes
|
data/README.markdown
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
A library for safe evaluation of Ruby code based on RubyParser and
|
4
4
|
Ruby2Ruby. Provides Rails ActionView template handlers for ERB and Haml.
|
5
5
|
|
6
|
+
[](https://travis-ci.org/svenfuchs/safemode)
|
7
|
+
|
6
8
|
### Word of warning
|
7
9
|
|
8
10
|
This library is still highly experimental. Only use it at your own risk for
|
@@ -52,9 +54,9 @@ class is only accessible when returned by a method or passed into a template.
|
|
52
54
|
For more details about the concepts behind Safemode please refer to the
|
53
55
|
following blog posts until a more comprehensive writeup is available:
|
54
56
|
|
55
|
-
* Initial reasoning:
|
56
|
-
* Refined concept:
|
57
|
-
* ActionView ERB handler:
|
57
|
+
* Initial reasoning: http://www.artweb-design.de/2008/2/5/sexy-theme-templating-with-haml-safemode-finally
|
58
|
+
* Refined concept: http://www.artweb-design.de/2008/2/17/sending-ruby-to-the-jail-an-attemp-on-a-haml-safemode
|
59
|
+
* ActionView ERB handler: http://www.artweb-design.de/2008/4/22/an-erb-safemode-handler-for-actionview
|
58
60
|
|
59
61
|
### Dependencies
|
60
62
|
|
@@ -64,14 +66,14 @@ Requires the gems:
|
|
64
66
|
* Ruby2Ruby
|
65
67
|
|
66
68
|
As of writing RubyParser alters StringIO and thus breaks usage with Rails.
|
67
|
-
See
|
69
|
+
See http://www.zenspider.com/pipermail/parsetree/2008-April/000026.html
|
68
70
|
|
69
71
|
A patch is included that fixes this issue and can be applied to RubyParser.
|
70
72
|
See lib/ruby\_parser\_string\_io\_patch.diff
|
71
73
|
|
72
74
|
### Credits
|
73
75
|
|
74
|
-
* Sven Fuchs - Maintainer
|
76
|
+
* Sven Fuchs - Initial Maintainer
|
75
77
|
* Peter Cooper
|
76
78
|
* Matthias Viehweger
|
77
79
|
* Ohad Levy
|
data/Rakefile
CHANGED
@@ -23,7 +23,7 @@ require 'jeweler'
|
|
23
23
|
Jeweler::Tasks.new do |gem|
|
24
24
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
25
25
|
gem.name = "safemode"
|
26
|
-
gem.homepage = "
|
26
|
+
gem.homepage = "https://github.com/svenfuchs/safemode"
|
27
27
|
gem.license = "MIT"
|
28
28
|
gem.summary = %Q{A library for safe evaluation of Ruby code based on ParseTree/RubyParser and Ruby2Ruby}
|
29
29
|
gem.description = %Q{A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby. Provides Rails ActionView template handlers for ERB and Haml.}
|
@@ -36,6 +36,7 @@ Jeweler::Tasks.new do |gem|
|
|
36
36
|
"Ohad Levy",
|
37
37
|
"Dmitri Dolguikh",
|
38
38
|
]
|
39
|
+
gem.files.exclude '.travis.yml'
|
39
40
|
# dependencies defined in Gemfile
|
40
41
|
end
|
41
42
|
Jeweler::RubygemsDotOrgTasks.new
|
@@ -47,20 +48,10 @@ Rake::TestTask.new(:test) do |test|
|
|
47
48
|
test.verbose = true
|
48
49
|
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
Rake::Task[:test].execute
|
55
|
-
end
|
56
|
-
else
|
57
|
-
require 'rcov/rcovtask'
|
58
|
-
Rcov::RcovTask.new do |test|
|
59
|
-
test.libs << 'test'
|
60
|
-
test.pattern = 'test/**/test_*.rb'
|
61
|
-
test.verbose = true
|
62
|
-
test.rcov_opts << '--exclude "gems/*"'
|
63
|
-
end
|
51
|
+
desc "Generate coverage report for tests"
|
52
|
+
task :coverage do |cov|
|
53
|
+
ENV['COVERAGE'] = 'true'
|
54
|
+
Rake::Task[:test].execute
|
64
55
|
end
|
65
56
|
|
66
57
|
task :default => :test
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.6
|
@@ -20,9 +20,9 @@ module ActionView
|
|
20
20
|
|
21
21
|
# code = ::ERB.new(src, nil, @view.erb_trim_mode).src
|
22
22
|
code = ::ERB.new("<% __in_erb_template=true %>#{src}", nil, erb_trim_mode, '@output_buffer').src
|
23
|
-
# Ruby 1.9 prepends an encoding to the source. However this is
|
23
|
+
# Ruby 1.9+ prepends an encoding to the source. However this is
|
24
24
|
# useless because you can only set an encoding on the first line
|
25
|
-
|
25
|
+
src.sub(/\A#coding:.*\n/, '') : src
|
26
26
|
|
27
27
|
code.gsub!('\\','\\\\\\') # backslashes would disappear in compile_template/modul_eval, so we escape them
|
28
28
|
|
data/lib/safemode/blankslate.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Safemode
|
2
2
|
class Blankslate
|
3
3
|
@@allow_instance_methods = ['class', 'methods', 'respond_to?', 'respond_to_missing?', 'to_s', 'instance_variable_get']
|
4
|
-
@@allow_class_methods = ['methods', 'new', 'name', '<', 'ancestors', '=='] # < needed in Rails Object#subclasses_of
|
4
|
+
@@allow_class_methods = ['singleton_class?', 'methods', 'new', 'name', '<', 'ancestors', '=='] # < needed in Rails Object#subclasses_of
|
5
5
|
if defined?(JRUBY_VERSION)
|
6
6
|
# JRuby seems to silently fail to remove method_missing
|
7
7
|
# (also see https://github.com/jruby/jruby/blob/9.1.7.0/core/src/main/java/org/jruby/RubyModule.java#L1109)
|
data/lib/safemode/core_jails.rb
CHANGED
@@ -41,18 +41,18 @@ module Safemode
|
|
41
41
|
# these methods are allowed in all classes if they are present
|
42
42
|
@@default_methods = %w( % & * ** + +@ - -@ / < << <= <=> ! != == === > >= >> ^ | ~
|
43
43
|
eql? equal? new methods is_a? kind_of? nil?
|
44
|
-
[] []= to_a to_jail to_s inspect to_param not)
|
44
|
+
[] []= to_a to_jail to_s inspect to_param not freeze)
|
45
45
|
|
46
46
|
# whitelisted methods for core classes ... kind of arbitrary selection
|
47
47
|
@@methods_whitelist = {
|
48
48
|
'Array' => %w(any? assoc at blank? collect collect! compact compact!
|
49
49
|
concat delete delete_at delete_if each each_index empty?
|
50
50
|
fetch fill first flatten flatten! hash include? index
|
51
|
-
indexes indices inject insert join last length map map!
|
51
|
+
indexes indices inject insert join last length map map! max min
|
52
52
|
nitems pop push present? rassoc reject reject! reverse
|
53
53
|
reverse! reverse_each rindex select shift size slice
|
54
|
-
slice! sort sort! transpose uniq uniq! unshift
|
55
|
-
zip),
|
54
|
+
slice! sort sort! transpose to_sentence uniq uniq! unshift
|
55
|
+
values_at zip),
|
56
56
|
|
57
57
|
'Bignum' => %w(abs blank? ceil chr coerce div divmod downto floor hash
|
58
58
|
integer? modulo next nonzero? present? quo remainder round
|
@@ -70,7 +70,7 @@ module Safemode
|
|
70
70
|
to_int to_s truncate zero?),
|
71
71
|
|
72
72
|
'Hash' => %w(any? blank? clear delete delete_if each each_key
|
73
|
-
each_pair each_value empty? fetch has_key? has_value?
|
73
|
+
each_pair each_value empty? fetch dig has_key? has_value?
|
74
74
|
include? index invert key? keys length member? merge merge!
|
75
75
|
present? rec_merge! rehash reject reject! select shift
|
76
76
|
size sort store update value? values values_at),
|
data/lib/safemode/jail.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
module Safemode
|
2
|
-
class Jail < Blankslate
|
1
|
+
module Safemode
|
2
|
+
class Jail < Blankslate
|
3
3
|
def initialize(source = nil)
|
4
4
|
@source = source
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
def to_jail
|
8
8
|
self
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def to_s
|
12
12
|
@source.to_s
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def method_missing(method, *args, &block)
|
16
16
|
if @source.is_a?(Class)
|
17
17
|
unless self.class.allowed_class_method?(method)
|
@@ -22,7 +22,7 @@ module Safemode
|
|
22
22
|
raise Safemode::NoMethodError.new("##{method}", self.class.name, @source.class.name)
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
# As every call to an object in the eval'ed string will be jailed by the
|
27
27
|
# parser we don't need to "proactively" jail arrays and hashes. Likewise we
|
28
28
|
# don't need to jail objects returned from a jail. Doing so would provide
|
@@ -31,11 +31,6 @@ module Safemode
|
|
31
31
|
@source.send(method, *args, &block)
|
32
32
|
end
|
33
33
|
|
34
|
-
# needed for compatibility with 1.8.7; remove this method once 1.8.7 support has been dropped
|
35
|
-
def respond_to?(method, *)
|
36
|
-
respond_to_missing?(method)
|
37
|
-
end
|
38
|
-
|
39
34
|
def respond_to_missing?(method_name, include_private = false)
|
40
35
|
self.class.allowed_instance_method?(method_name)
|
41
36
|
end
|
data/lib/safemode/parser.rb
CHANGED
@@ -121,8 +121,8 @@ module Safemode
|
|
121
121
|
|
122
122
|
def process_const(arg)
|
123
123
|
sexp_type = arg.sexp_body.sexp_type # constants are encoded as: "s(:const, :Encoding)"
|
124
|
-
if
|
125
|
-
# handling of Encoding constants
|
124
|
+
if sexp_type == :Encoding
|
125
|
+
# handling of Encoding constants.
|
126
126
|
# Note: ruby_parser evaluates __ENCODING__ to s(:colon2, s(:const, :Encoding), :UTF_8)
|
127
127
|
"#{super(arg).gsub('-', '_')}"
|
128
128
|
elsif sexp_type == :String
|
data/safemode.gemspec
CHANGED
@@ -2,25 +2,25 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: safemode 1.3.
|
5
|
+
# stub: safemode 1.3.7 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
|
-
s.name = "safemode"
|
9
|
-
s.version = "1.3.
|
8
|
+
s.name = "safemode".freeze
|
9
|
+
s.version = "1.3.7"
|
10
10
|
|
11
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
-
s.require_paths = ["lib"]
|
13
|
-
s.authors = ["Sven Fuchs", "Peter Cooper", "Matthias Viehweger", "Kingsley Hendrickse", "Ohad Levy", "Dmitri Dolguikh"]
|
14
|
-
s.date = "
|
15
|
-
s.description = "A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby. Provides Rails ActionView template handlers for ERB and Haml."
|
16
|
-
s.email = "ohadlevy@gmail.com"
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["Sven Fuchs".freeze, "Peter Cooper".freeze, "Matthias Viehweger".freeze, "Kingsley Hendrickse".freeze, "Ohad Levy".freeze, "Dmitri Dolguikh".freeze]
|
14
|
+
s.date = "2022-04-26"
|
15
|
+
s.description = "A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby. Provides Rails ActionView template handlers for ERB and Haml.".freeze
|
16
|
+
s.email = "ohadlevy@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
18
19
|
"README.markdown"
|
19
20
|
]
|
20
21
|
s.files = [
|
21
|
-
".travis.yml",
|
22
22
|
"Gemfile",
|
23
|
-
"
|
23
|
+
"LICENSE",
|
24
24
|
"README.markdown",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
@@ -47,48 +47,42 @@ Gem::Specification.new do |s|
|
|
47
47
|
"test/test_safemode_eval.rb",
|
48
48
|
"test/test_safemode_parser.rb"
|
49
49
|
]
|
50
|
-
s.homepage = "
|
51
|
-
s.licenses = ["MIT"]
|
52
|
-
s.rubygems_version = "2.
|
53
|
-
s.summary = "A library for safe evaluation of Ruby code based on ParseTree/RubyParser and Ruby2Ruby"
|
50
|
+
s.homepage = "https://github.com/svenfuchs/safemode".freeze
|
51
|
+
s.licenses = ["MIT".freeze]
|
52
|
+
s.rubygems_version = "2.7.6".freeze
|
53
|
+
s.summary = "A library for safe evaluation of Ruby code based on ParseTree/RubyParser and Ruby2Ruby".freeze
|
54
54
|
|
55
55
|
if s.respond_to? :specification_version then
|
56
56
|
s.specification_version = 4
|
57
57
|
|
58
58
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
|
-
s.add_runtime_dependency(%q<
|
60
|
-
s.add_runtime_dependency(%q<
|
61
|
-
s.add_runtime_dependency(%q<
|
62
|
-
s.add_development_dependency(%q<
|
63
|
-
s.add_development_dependency(%q<
|
64
|
-
s.add_development_dependency(%q<
|
65
|
-
s.add_development_dependency(%q<
|
66
|
-
s.add_development_dependency(%q<
|
67
|
-
s.add_development_dependency(%q<test-unit>, [">= 0"])
|
68
|
-
s.add_development_dependency(%q<rake>, [">= 0"])
|
59
|
+
s.add_runtime_dependency(%q<ruby2ruby>.freeze, [">= 2.4.0"])
|
60
|
+
s.add_runtime_dependency(%q<ruby_parser>.freeze, [">= 3.10.1"])
|
61
|
+
s.add_runtime_dependency(%q<sexp_processor>.freeze, [">= 4.10.0"])
|
62
|
+
s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
|
63
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
64
|
+
s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
|
65
|
+
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
66
|
+
s.add_development_dependency(%q<test-unit>.freeze, [">= 0"])
|
69
67
|
else
|
70
|
-
s.add_dependency(%q<
|
71
|
-
s.add_dependency(%q<
|
72
|
-
s.add_dependency(%q<
|
73
|
-
s.add_dependency(%q<
|
74
|
-
s.add_dependency(%q<
|
75
|
-
s.add_dependency(%q<
|
76
|
-
s.add_dependency(%q<
|
77
|
-
s.add_dependency(%q<
|
78
|
-
s.add_dependency(%q<test-unit>, [">= 0"])
|
79
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
68
|
+
s.add_dependency(%q<ruby2ruby>.freeze, [">= 2.4.0"])
|
69
|
+
s.add_dependency(%q<ruby_parser>.freeze, [">= 3.10.1"])
|
70
|
+
s.add_dependency(%q<sexp_processor>.freeze, [">= 4.10.0"])
|
71
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
72
|
+
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
73
|
+
s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
|
74
|
+
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
75
|
+
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
80
76
|
end
|
81
77
|
else
|
82
|
-
s.add_dependency(%q<
|
83
|
-
s.add_dependency(%q<
|
84
|
-
s.add_dependency(%q<
|
85
|
-
s.add_dependency(%q<
|
86
|
-
s.add_dependency(%q<
|
87
|
-
s.add_dependency(%q<
|
88
|
-
s.add_dependency(%q<
|
89
|
-
s.add_dependency(%q<
|
90
|
-
s.add_dependency(%q<test-unit>, [">= 0"])
|
91
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
78
|
+
s.add_dependency(%q<ruby2ruby>.freeze, [">= 2.4.0"])
|
79
|
+
s.add_dependency(%q<ruby_parser>.freeze, [">= 3.10.1"])
|
80
|
+
s.add_dependency(%q<sexp_processor>.freeze, [">= 4.10.0"])
|
81
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
82
|
+
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
83
|
+
s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
|
84
|
+
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
85
|
+
s.add_dependency(%q<test-unit>.freeze, [">= 0"])
|
92
86
|
end
|
93
87
|
end
|
94
88
|
|
data/test/test_helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
if
|
1
|
+
if ENV['COVERAGE']
|
2
2
|
require 'simplecov'
|
3
3
|
SimpleCov.start {add_filter 'test_'}
|
4
4
|
end
|
@@ -22,7 +22,7 @@ module TestHelper
|
|
22
22
|
'@article.comment_class.new',
|
23
23
|
'String.instance_variable_set :@a, :a' ]
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def security_error_raising_calls
|
27
27
|
[ "class A\n end",
|
28
28
|
'File.open("/etc/passwd")',
|
@@ -42,10 +42,10 @@ module TestHelper
|
|
42
42
|
"attr_reader :a",
|
43
43
|
'URI("http://google.com")',
|
44
44
|
"`ls -a`", "exec('echo *')", "syscall 4, 1, 'hello', 5", "system('touch /tmp/helloworld')",
|
45
|
-
"abort",
|
45
|
+
"abort",
|
46
46
|
"exit(0)", "exit!(0)", "at_exit{'goodbye'}",
|
47
47
|
"autoload(::MyModule, 'my_module.rb')",
|
48
|
-
"binding",
|
48
|
+
"binding",
|
49
49
|
"callcc{|cont| cont.call}",
|
50
50
|
'eval %Q(send(:system, "ls -a"))',
|
51
51
|
"fork",
|
@@ -58,12 +58,12 @@ module TestHelper
|
|
58
58
|
"open('/etc/passwd'){|f| f.read}",
|
59
59
|
"p 'text'", "pretty_inspect",
|
60
60
|
# "print 'text'", "puts 'text'", allowed and buffered these (see ScopeObject)
|
61
|
-
"printf 'text'", "putc 'a'",
|
61
|
+
"printf 'text'", "putc 'a'",
|
62
62
|
"raise RuntimeError, 'should not happen'",
|
63
|
-
"rand(0)", "srand(0)",
|
63
|
+
"rand(0)", "srand(0)",
|
64
64
|
"set_trace_func proc{|event| puts event}", "trace_var :$_, proc {|v| puts v }", "untrace_var :$_",
|
65
|
-
"sleep", "sleep(0)",
|
66
|
-
"test(1, a, b)",
|
65
|
+
"sleep", "sleep(0)",
|
66
|
+
"test(1, a, b)",
|
67
67
|
"Signal.trap(0, proc { puts 'Terminating: #{$$}' })",
|
68
68
|
"warn 'warning'",
|
69
69
|
'Array.new' ]
|
@@ -77,31 +77,31 @@ module TestHelper
|
|
77
77
|
def assert_raise_security(code = nil, assigns = {}, locals = {}, &block)
|
78
78
|
assert_raise_safemode_error(Safemode::SecurityError, code, assigns, locals, &block)
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def assert_raise_safemode_error(error, code, assigns = {}, locals = {})
|
82
82
|
code = yield(code) if block_given?
|
83
83
|
assert_raise(error, code) { safebox_eval(code, assigns, locals) }
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
def safebox_eval(code, assigns = {}, locals = {})
|
87
87
|
# puts Safemode::Parser.jail(code)
|
88
88
|
Safemode::Box.new.eval code, assigns, locals
|
89
|
-
end
|
89
|
+
end
|
90
90
|
end
|
91
91
|
|
92
92
|
class Article
|
93
93
|
def is_article?
|
94
94
|
true
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
def title
|
98
98
|
'an article title'
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
def to_jail
|
102
102
|
Article::Jail.new self
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
def comments
|
106
106
|
[Comment.new(self), Comment.new(self)]
|
107
107
|
end
|
@@ -117,15 +117,15 @@ end
|
|
117
117
|
|
118
118
|
class Comment
|
119
119
|
attr_reader :article
|
120
|
-
|
120
|
+
|
121
121
|
def initialize(article)
|
122
122
|
@article = article
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
def text
|
126
126
|
"comment #{object_id}"
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
def to_jail
|
130
130
|
Comment::Jail.new self
|
131
131
|
end
|
@@ -145,7 +145,7 @@ end
|
|
145
145
|
|
146
146
|
class Article::Jail < Safemode::Jail
|
147
147
|
allow :title, :comments, :is_article?, :comment_class
|
148
|
-
|
148
|
+
|
149
149
|
def author_name
|
150
150
|
"this article's author name"
|
151
151
|
end
|
@@ -155,6 +155,21 @@ class Article::ExtendedJail < Article::Jail
|
|
155
155
|
end
|
156
156
|
|
157
157
|
class Comment::Jail < Safemode::Jail
|
158
|
-
allow :article, :text
|
158
|
+
allow :article, :text, :object_id
|
159
159
|
allow_class_method :all
|
160
160
|
end
|
161
|
+
|
162
|
+
class ExtendedComment < Comment
|
163
|
+
def extended_text
|
164
|
+
"extended comment #{object_id}"
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_jail
|
168
|
+
ExtendedComment::Jail.new self
|
169
|
+
end
|
170
|
+
|
171
|
+
class Jail < Comment::Jail
|
172
|
+
allow :extended_text
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
data/test/test_jail.rb
CHANGED
@@ -5,6 +5,7 @@ class TestJail < Test::Unit::TestCase
|
|
5
5
|
@article = Article.new.to_jail
|
6
6
|
@comment = @article.comments.first
|
7
7
|
@comment_class = Comment.to_jail
|
8
|
+
@extended_comment = ExtendedComment.new(@article).to_jail
|
8
9
|
end
|
9
10
|
|
10
11
|
def test_explicitly_allowed_instance_methods_should_be_accessible
|
@@ -24,8 +25,7 @@ class TestJail < Test::Unit::TestCase
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def test_jail_instances_should_have_limited_methods
|
27
|
-
expected = ["class", "method_missing", "methods", "respond_to?", "
|
28
|
-
expected.delete('respond_to_missing?') if RUBY_VERSION > '1.9.3' # respond_to_missing? is private in rubies above 1.9.3
|
28
|
+
expected = ["class", "method_missing", "methods", "respond_to?", "to_jail", "to_s", "instance_variable_get"]
|
29
29
|
objects.each do |object|
|
30
30
|
assert_equal expected.sort, reject_pretty_methods(object.to_jail.methods.map(&:to_s).sort)
|
31
31
|
end
|
@@ -37,7 +37,8 @@ class TestJail < Test::Unit::TestCase
|
|
37
37
|
"allow_instance_method", "allow_class_method", "allowed_instance_method?",
|
38
38
|
"allowed_class_method?", "allowed_instance_methods", "allowed_class_methods",
|
39
39
|
"<", # < needed in Rails Object#subclasses_of
|
40
|
-
"ancestors", "=="
|
40
|
+
"ancestors", "==", # ancestors and == needed in Rails::Generator::Spec#lookup_class
|
41
|
+
"singleton_class?" ]
|
41
42
|
|
42
43
|
if defined?(JRUBY_VERSION)
|
43
44
|
(expected << ['method_missing', 'singleton_method_undefined', 'singleton_method_added']).flatten! # needed for running under jruby
|
@@ -57,6 +58,14 @@ class TestJail < Test::Unit::TestCase
|
|
57
58
|
assert !@article.respond_to?(:bogus)
|
58
59
|
end
|
59
60
|
|
61
|
+
def test_methodcall_comment
|
62
|
+
assert_equal "comment #{@comment.object_id}", @comment.text
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_methodcall_extended_comment
|
66
|
+
assert_equal "extended comment #{@extended_comment.object_id}", @extended_comment.extended_text
|
67
|
+
end
|
68
|
+
|
60
69
|
private
|
61
70
|
|
62
71
|
def objects
|
data/test/test_safemode_eval.rb
CHANGED
@@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), 'test_helper')
|
|
2
2
|
|
3
3
|
class TestSafemodeEval < Test::Unit::TestCase
|
4
4
|
include TestHelper
|
5
|
-
|
5
|
+
|
6
6
|
def setup
|
7
7
|
@box = Safemode::Box.new
|
8
8
|
@locals = { :article => Article.new }
|
@@ -18,14 +18,10 @@ class TestSafemodeEval < Test::Unit::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_unary_operators_on_instances_of_boolean_vars
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
assert !@box.eval('!true')
|
26
|
-
else
|
27
|
-
p "no unary ops under 1.8.7!"
|
28
|
-
end
|
21
|
+
assert @box.eval('not false')
|
22
|
+
assert @box.eval('!false')
|
23
|
+
assert !@box.eval('not true')
|
24
|
+
assert !@box.eval('!true')
|
29
25
|
end
|
30
26
|
|
31
27
|
def test_false_class_ops
|
@@ -55,35 +51,35 @@ class TestSafemodeEval < Test::Unit::TestCase
|
|
55
51
|
def test_should_turn_assigns_to_jails
|
56
52
|
assert_raise_no_method "@article.system", @assigns
|
57
53
|
end
|
58
|
-
|
54
|
+
|
59
55
|
def test_should_turn_locals_to_jails
|
60
56
|
assert_raise(Safemode::NoMethodError){ @box.eval "article.system", {}, @locals }
|
61
57
|
end
|
62
|
-
|
58
|
+
|
63
59
|
def test_should_allow_method_access_on_assigns
|
64
60
|
assert_nothing_raised{ @box.eval "@article.title", @assigns }
|
65
61
|
end
|
66
|
-
|
62
|
+
|
67
63
|
def test_should_allow_method_access_on_locals
|
68
64
|
assert_nothing_raised{ @box.eval("article.title", {}, @locals) }
|
69
65
|
end
|
70
|
-
|
66
|
+
|
71
67
|
def test_should_not_raise_on_if_using_return_values
|
72
68
|
assert_nothing_raised{ @box.eval "if @article.is_article? then 1 end", @assigns }
|
73
69
|
end
|
74
|
-
|
70
|
+
|
75
71
|
def test_should_work_with_if_using_return_values
|
76
72
|
assert_equal @box.eval("if @article.is_article? then 1 end", @assigns), 1
|
77
73
|
end
|
78
|
-
|
74
|
+
|
79
75
|
def test__FILE__should_not_render_filename
|
80
76
|
assert_equal '(string)', @box.eval("__FILE__")
|
81
77
|
end
|
82
|
-
|
78
|
+
|
83
79
|
def test_interpolated_xstr_should_raise_security
|
84
80
|
assert_raise_security '"#{`ls -a`}"'
|
85
|
-
end
|
86
|
-
|
81
|
+
end
|
82
|
+
|
87
83
|
TestHelper.no_method_error_raising_calls.each do |call|
|
88
84
|
call.gsub!('"', '\\\\"')
|
89
85
|
class_eval %Q(
|
@@ -100,6 +96,6 @@ class TestSafemodeEval < Test::Unit::TestCase
|
|
100
96
|
assert_raise_security "#{call}", @assigns, @locals
|
101
97
|
end
|
102
98
|
)
|
103
|
-
end
|
99
|
+
end
|
104
100
|
|
105
101
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safemode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Fuchs
|
@@ -10,25 +10,11 @@ authors:
|
|
10
10
|
- Kingsley Hendrickse
|
11
11
|
- Ohad Levy
|
12
12
|
- Dmitri Dolguikh
|
13
|
-
autorequire:
|
13
|
+
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2022-04-26 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
|
-
- !ruby/object:Gem::Dependency
|
19
|
-
name: sexp_processor
|
20
|
-
requirement: !ruby/object:Gem::Requirement
|
21
|
-
requirements:
|
22
|
-
- - ">="
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: 4.10.0
|
25
|
-
type: :runtime
|
26
|
-
prerelease: false
|
27
|
-
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
requirements:
|
29
|
-
- - ">="
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version: 4.10.0
|
32
18
|
- !ruby/object:Gem::Dependency
|
33
19
|
name: ruby2ruby
|
34
20
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,33 +44,19 @@ dependencies:
|
|
58
44
|
- !ruby/object:Gem::Version
|
59
45
|
version: 3.10.1
|
60
46
|
- !ruby/object:Gem::Dependency
|
61
|
-
name:
|
62
|
-
requirement: !ruby/object:Gem::Requirement
|
63
|
-
requirements:
|
64
|
-
- - "~>"
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: '3.12'
|
67
|
-
type: :development
|
68
|
-
prerelease: false
|
69
|
-
version_requirements: !ruby/object:Gem::Requirement
|
70
|
-
requirements:
|
71
|
-
- - "~>"
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
version: '3.12'
|
74
|
-
- !ruby/object:Gem::Dependency
|
75
|
-
name: bundler
|
47
|
+
name: sexp_processor
|
76
48
|
requirement: !ruby/object:Gem::Requirement
|
77
49
|
requirements:
|
78
|
-
- - "
|
50
|
+
- - ">="
|
79
51
|
- !ruby/object:Gem::Version
|
80
|
-
version:
|
81
|
-
type: :
|
52
|
+
version: 4.10.0
|
53
|
+
type: :runtime
|
82
54
|
prerelease: false
|
83
55
|
version_requirements: !ruby/object:Gem::Requirement
|
84
56
|
requirements:
|
85
|
-
- - "
|
57
|
+
- - ">="
|
86
58
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
59
|
+
version: 4.10.0
|
88
60
|
- !ruby/object:Gem::Dependency
|
89
61
|
name: jeweler
|
90
62
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,7 +72,7 @@ dependencies:
|
|
100
72
|
- !ruby/object:Gem::Version
|
101
73
|
version: '0'
|
102
74
|
- !ruby/object:Gem::Dependency
|
103
|
-
name:
|
75
|
+
name: rake
|
104
76
|
requirement: !ruby/object:Gem::Requirement
|
105
77
|
requirements:
|
106
78
|
- - ">="
|
@@ -114,21 +86,21 @@ dependencies:
|
|
114
86
|
- !ruby/object:Gem::Version
|
115
87
|
version: '0'
|
116
88
|
- !ruby/object:Gem::Dependency
|
117
|
-
name:
|
89
|
+
name: rdoc
|
118
90
|
requirement: !ruby/object:Gem::Requirement
|
119
91
|
requirements:
|
120
|
-
- - "
|
92
|
+
- - "~>"
|
121
93
|
- !ruby/object:Gem::Version
|
122
|
-
version: '
|
94
|
+
version: '3.12'
|
123
95
|
type: :development
|
124
96
|
prerelease: false
|
125
97
|
version_requirements: !ruby/object:Gem::Requirement
|
126
98
|
requirements:
|
127
|
-
- - "
|
99
|
+
- - "~>"
|
128
100
|
- !ruby/object:Gem::Version
|
129
|
-
version: '
|
101
|
+
version: '3.12'
|
130
102
|
- !ruby/object:Gem::Dependency
|
131
|
-
name:
|
103
|
+
name: simplecov
|
132
104
|
requirement: !ruby/object:Gem::Requirement
|
133
105
|
requirements:
|
134
106
|
- - ">="
|
@@ -142,7 +114,7 @@ dependencies:
|
|
142
114
|
- !ruby/object:Gem::Version
|
143
115
|
version: '0'
|
144
116
|
- !ruby/object:Gem::Dependency
|
145
|
-
name:
|
117
|
+
name: test-unit
|
146
118
|
requirement: !ruby/object:Gem::Requirement
|
147
119
|
requirements:
|
148
120
|
- - ">="
|
@@ -161,11 +133,11 @@ email: ohadlevy@gmail.com
|
|
161
133
|
executables: []
|
162
134
|
extensions: []
|
163
135
|
extra_rdoc_files:
|
136
|
+
- LICENSE
|
164
137
|
- README.markdown
|
165
138
|
files:
|
166
|
-
- ".travis.yml"
|
167
139
|
- Gemfile
|
168
|
-
-
|
140
|
+
- LICENSE
|
169
141
|
- README.markdown
|
170
142
|
- Rakefile
|
171
143
|
- VERSION
|
@@ -191,11 +163,11 @@ files:
|
|
191
163
|
- test/test_jail.rb
|
192
164
|
- test/test_safemode_eval.rb
|
193
165
|
- test/test_safemode_parser.rb
|
194
|
-
homepage:
|
166
|
+
homepage: https://github.com/svenfuchs/safemode
|
195
167
|
licenses:
|
196
168
|
- MIT
|
197
169
|
metadata: {}
|
198
|
-
post_install_message:
|
170
|
+
post_install_message:
|
199
171
|
rdoc_options: []
|
200
172
|
require_paths:
|
201
173
|
- lib
|
@@ -210,9 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
182
|
- !ruby/object:Gem::Version
|
211
183
|
version: '0'
|
212
184
|
requirements: []
|
213
|
-
|
214
|
-
|
215
|
-
signing_key:
|
185
|
+
rubygems_version: 3.0.3
|
186
|
+
signing_key:
|
216
187
|
specification_version: 4
|
217
188
|
summary: A library for safe evaluation of Ruby code based on ParseTree/RubyParser
|
218
189
|
and Ruby2Ruby
|