safemode 1.5.0 → 1.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 795ca593ca92570d9d4a54cbad72c18c32574d1190b37d002acb22f0347814e0
4
- data.tar.gz: 585a9de965e98cc5f7d847357db1db8ce2a52e1200cf17169dc109c4cda231b5
3
+ metadata.gz: 60d02e15fb3d2ae2d1447e72e0c92e7379c826393b64349ce3c2c71ca4d53da5
4
+ data.tar.gz: 3cb324e0289157a132e5edd0535cc66d6ae351acf737b092d74a68859ebfe887
5
5
  SHA512:
6
- metadata.gz: d27b2e9fa7e9893cc43039c37c884e21c1e7945974d3614a907818453e99b88d0cd37ab68d43058e01303f3d6bc6966f51edeee009a712994ad40b754660a4d7
7
- data.tar.gz: 1b6ddc2ab11f82cc6275d9ea26aa57800ebcfc2a2e7a84612894bb61b17a879e1b83eac20dff722091fab596eeb04912110d4bb70dbcce924771b189c218894f
6
+ metadata.gz: 364354811cc8928d257da2d095e4aed8301eb5d26a7d2303d8f0be5e9d16a1c9172f04c967c385a31ea24af95dc6c2eb00ef2fd7eb47426872db0064a5035cd0
7
+ data.tar.gz: 01f78d9d81dffa08d50068177840324c7d54db94249a3714b34d2e2301386836a061c85da2ce4d610c8890f60427b76bb2fa3bb2f7e90a917a6c2316ff58c13b
data/demo.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'safemode'
2
4
  require 'erb'
3
5
 
@@ -17,15 +17,11 @@ module Safemode
17
17
  end
18
18
 
19
19
  def core_classes
20
- klasses = [ Array, Float, Hash, Range, String, Symbol, Time, NilClass, FalseClass, TrueClass ]
20
+ klasses = [ Array, Float, Hash, Integer, Range, String, Symbol, Time, NilClass, FalseClass, TrueClass ]
21
21
  klasses << Date if defined? Date
22
22
  klasses << DateTime if defined? DateTime
23
- if RUBY_VERSION >= '2.4.0'
24
- klasses << Integer
25
- else
26
- klasses << Bignum
27
- klasses << Fixnum
28
- end
23
+ klasses << Data if defined? Data # Ruby 3.2 addition
24
+ klasses << Set if defined? Set # Ruby 3.2 addition
29
25
  klasses
30
26
  end
31
27
 
@@ -46,31 +42,21 @@ module Safemode
46
42
  # whitelisted methods for core classes ... kind of arbitrary selection
47
43
  @@methods_whitelist = {
48
44
  'Array' => %w(any? assoc at blank? collect collect! compact compact!
49
- concat delete delete_at delete_if each each_index empty?
50
- fetch fill first flatten flatten! hash include? index
45
+ concat delete delete_at delete_if each each_index each_with_index
46
+ empty? fetch fill first flatten flatten! hash include? index
51
47
  indexes indices inject insert join last length map map! max min
52
48
  nitems pop push present? rassoc reject reject! reverse
53
49
  reverse! reverse_each rindex select shift size slice
54
50
  slice! sort sort! transpose to_sentence uniq uniq! unshift
55
51
  values_at zip),
56
52
 
57
- 'Bignum' => %w(abs blank? ceil chr coerce div divmod downto floor hash
58
- integer? modulo next nonzero? present? quo remainder round
59
- singleton_method_added size step succ times to_f to_i
60
- to_int to_s truncate upto zero?),
61
-
62
- 'Fixnum' => %w(abs blank? ceil chr coerce div divmod downto floor id2name
63
- integer? modulo modulo next nonzero? present? quo remainder
64
- round singleton_method_added size step succ times to_f to_i
65
- to_int to_s to_sym truncate upto zero?),
66
-
67
53
  'Float' => %w(abs blank? ceil coerce div divmod finite? floor hash
68
54
  infinite? integer? modulo nan? nonzero? present? quo
69
55
  remainder round singleton_method_added step to_f to_i
70
56
  to_int to_s truncate zero?),
71
57
 
72
- 'Hash' => %w(any? blank? clear delete delete_if each each_key
73
- each_pair each_value empty? fetch dig has_key? has_value?
58
+ 'Hash' => %w(any? blank? clear delete delete_if each each_key each_pair
59
+ each_value each_with_index empty? fetch dig has_key? has_value?
74
60
  include? index invert key? keys length member? merge merge!
75
61
  present? rec_merge! rehash reject reject! select shift
76
62
  size sort store update value? values values_at),
@@ -116,6 +102,17 @@ module Safemode
116
102
  'DateTime' => %w(blank? hour min new_offset newof of offset present? sec
117
103
  sec_fraction strftime to_datetime_default_s to_json zone),
118
104
 
105
+ 'Data' => %w(deconstruct deconstruct_keys hash members),
106
+
107
+ 'Set' => %w(any? blank? clear clone collect count delete delete?
108
+ delete_if difference disjoint? each each_with_index
109
+ each_with_object empty? filter find first flatten
110
+ flatten! hash include? inject intersect? intersection
111
+ join keep_if length map max member? merge min
112
+ present? reject reject! replace select select!
113
+ size sort sort_by subset? superset? union
114
+ uniq zip),
115
+
119
116
  'NilClass' => %w(blank? duplicable? present? to_f to_i),
120
117
 
121
118
  'FalseClass' => %w(blank? duplicable? present?),
@@ -1,6 +1,5 @@
1
1
  module Safemode
2
2
  class Parser < Ruby2Ruby
3
- # @@parser = defined?(RubyParser) ? 'RubyParser' : 'ParseTree'
4
3
  @@parser = 'RubyParser'
5
4
 
6
5
  class << self
@@ -12,8 +11,6 @@ module Safemode
12
11
 
13
12
  def parse(code)
14
13
  case @@parser
15
- # when 'ParseTree'
16
- # ParseTree.translate(code)
17
14
  when 'RubyParser'
18
15
  RubyParser.new.parse(code)
19
16
  else
@@ -90,7 +87,8 @@ module Safemode
90
87
  :colon2,
91
88
  # unnecessarily advanced?
92
89
  :argscat, :argspush, :splat,
93
- :op_asgn1, :op_asgn2, :op_asgn_and, :op_asgn_or,
90
+ :op_asgn, :op_asgn1, :op_asgn2, :op_asgn_and, :op_asgn_or,
91
+ :safe_op_asgn,
94
92
  # needed for haml
95
93
  :block ]
96
94
 
data/lib/safemode.rb CHANGED
@@ -5,13 +5,6 @@ begin
5
5
  require 'ruby_parser' # try to load RubyParser and use it if present
6
6
  rescue LoadError => e
7
7
  end
8
- # this doesn't work somehow. Maybe something changed inside
9
- # ParseTree or sexp_processor or so.
10
- # (the require itself works, but ParseTree doesn't play nice)
11
- # begin
12
- # require 'parse_tree'
13
- # rescue LoadError => e
14
- # end
15
8
 
16
9
  require 'safemode/core_ext'
17
10
  require 'safemode/blankslate'
data/safemode.gemspec CHANGED
@@ -4,10 +4,10 @@ require 'date'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "safemode".freeze
7
- s.version = "1.5.0"
7
+ s.version = "1.6.0"
8
8
  s.date = Date.today
9
9
 
10
- s.summary = "A library for safe evaluation of Ruby code based on ParseTree/RubyParser and Ruby2Ruby"
10
+ s.summary = "A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby"
11
11
  s.description = "A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby. Provides Rails ActionView template handlers for ERB and Haml."
12
12
  s.homepage = "https://github.com/svenfuchs/safemode"
13
13
  s.licenses = ["MIT"]
@@ -54,12 +54,12 @@ Gem::Specification.new do |s|
54
54
 
55
55
  s.required_ruby_version = ">= 2.7", "< 3.2"
56
56
 
57
- s.add_runtime_dependency "ruby2ruby", ">= 2.4.0"
58
- s.add_runtime_dependency "ruby_parser", ">= 3.10.1"
59
- s.add_runtime_dependency "sexp_processor", ">= 4.10.0"
57
+ s.add_runtime_dependency "ruby2ruby", "~> 2.4"
58
+ s.add_runtime_dependency "ruby_parser", "~> 3.10"
59
+ s.add_runtime_dependency "sexp_processor", "~> 4.10"
60
60
 
61
- s.add_development_dependency "rake"
62
- s.add_development_dependency "rdoc"
63
- s.add_development_dependency "simplecov"
64
- s.add_development_dependency "test-unit"
61
+ s.add_development_dependency "rake", "~> 13.4"
62
+ s.add_development_dependency "rdoc", "~> 7.2"
63
+ s.add_development_dependency "simplecov", "~> 0.22"
64
+ s.add_development_dependency "test-unit", "~> 3.7"
65
65
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.join(File.dirname(__FILE__), 'test_helper')
2
4
 
3
5
  class TestERBEval < Test::Unit::TestCase
@@ -58,19 +60,17 @@ class TestERBEval < Test::Unit::TestCase
58
60
  end
59
61
 
60
62
  TestHelper.no_method_error_raising_calls.each do |call|
61
- call.gsub!('"', '\\\\"')
62
63
  class_eval %Q(
63
64
  def test_calling_#{call.gsub(/[\W]/, '_')}_should_raise_no_method
64
- assert_raise_no_method "#{call}", @assigns, @locals
65
+ assert_raise_no_method "#{call.gsub('"', '\\\\"')}", @assigns, @locals
65
66
  end
66
67
  )
67
68
  end
68
69
 
69
70
  TestHelper.security_error_raising_calls.each do |call|
70
- call.gsub!('"', '\\\\"')
71
71
  class_eval %Q(
72
72
  def test_calling_#{call.gsub(/[\W]/, '_')}_should_raise_security
73
- assert_raise_security "#{call}", @assigns, @locals
73
+ assert_raise_security "#{call.gsub('"', '\\\\"')}", @assigns, @locals
74
74
  end
75
75
  )
76
76
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  if ENV['COVERAGE']
2
4
  require 'simplecov'
3
5
  SimpleCov.start {add_filter 'test_'}
data/test/test_jail.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.join(File.dirname(__FILE__), 'test_helper')
2
4
 
3
5
  class TestJail < Test::Unit::TestCase
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.join(File.dirname(__FILE__), 'test_helper')
2
4
 
3
5
  class TestSafemodeEval < Test::Unit::TestCase
@@ -98,20 +100,40 @@ class TestSafemodeEval < Test::Unit::TestCase
98
100
  end
99
101
  end
100
102
 
103
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2')
104
+ def test_pattern_matching_with_data_subclass
105
+ point_class = Data.define(:x, :y)
106
+ point = point_class.new(x: 10, y: 20)
107
+ assert_equal 10, @box.eval('case @point; in {x:}; x; end', { point: point })
108
+ end
109
+
110
+ def test_data_subclass_inherits_data_jail
111
+ point_class = Data.define(:x, :y)
112
+ point = point_class.new(x: 10, y: 20)
113
+ assert_equal [:x, :y], @box.eval('@point.members', { point: point })
114
+ assert_equal [10, 20], @box.eval('@point.deconstruct', { point: point })
115
+ assert_equal({ x: 10 }, @box.eval('@point.deconstruct_keys([:x])', { point: point }))
116
+ end
117
+
118
+ def test_data_subclass_jail_blocks_non_whitelisted_methods
119
+ point_class = Data.define(:x, :y)
120
+ point = point_class.new(x: 10, y: 20)
121
+ assert_raise(Safemode::NoMethodError) { @box.eval('@point.instance_variables', { point: point }) }
122
+ end
123
+ end
124
+
101
125
  TestHelper.no_method_error_raising_calls.each do |call|
102
- call.gsub!('"', '\\\\"')
103
126
  class_eval %Q(
104
127
  def test_calling_#{call.gsub(/[\W]/, '_')}_should_raise_no_method
105
- assert_raise_no_method "#{call}", @assigns, @locals
128
+ assert_raise_no_method "#{call.gsub('"', '\\\\"')}", @assigns, @locals
106
129
  end
107
130
  )
108
131
  end
109
132
 
110
133
  TestHelper.security_error_raising_calls.each do |call|
111
- call.gsub!('"', '\\\\"')
112
134
  class_eval %Q(
113
135
  def test_calling_#{call.gsub(/[\W]/, '_')}_should_raise_security
114
- assert_raise_security "#{call}", @assigns, @locals
136
+ assert_raise_security "#{call.gsub('"', '\\\\"')}", @assigns, @locals
115
137
  end
116
138
  )
117
139
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.join(File.dirname(__FILE__), 'test_helper')
2
4
 
3
5
  class TestSafemodeParser < Test::Unit::TestCase
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.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -13,106 +13,106 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2024-03-19 00:00:00.000000000 Z
16
+ date: 2026-05-21 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: ruby2ruby
20
20
  requirement: !ruby/object:Gem::Requirement
21
21
  requirements:
22
- - - ">="
22
+ - - "~>"
23
23
  - !ruby/object:Gem::Version
24
- version: 2.4.0
24
+ version: '2.4'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
- - - ">="
29
+ - - "~>"
30
30
  - !ruby/object:Gem::Version
31
- version: 2.4.0
31
+ version: '2.4'
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: ruby_parser
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  requirements:
36
- - - ">="
36
+ - - "~>"
37
37
  - !ruby/object:Gem::Version
38
- version: 3.10.1
38
+ version: '3.10'
39
39
  type: :runtime
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  requirements:
43
- - - ">="
43
+ - - "~>"
44
44
  - !ruby/object:Gem::Version
45
- version: 3.10.1
45
+ version: '3.10'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: sexp_processor
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  requirements:
50
- - - ">="
50
+ - - "~>"
51
51
  - !ruby/object:Gem::Version
52
- version: 4.10.0
52
+ version: '4.10'
53
53
  type: :runtime
54
54
  prerelease: false
55
55
  version_requirements: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ">="
57
+ - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: 4.10.0
59
+ version: '4.10'
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rake
62
62
  requirement: !ruby/object:Gem::Requirement
63
63
  requirements:
64
- - - ">="
64
+ - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: '0'
66
+ version: '13.4'
67
67
  type: :development
68
68
  prerelease: false
69
69
  version_requirements: !ruby/object:Gem::Requirement
70
70
  requirements:
71
- - - ">="
71
+ - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: '0'
73
+ version: '13.4'
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: rdoc
76
76
  requirement: !ruby/object:Gem::Requirement
77
77
  requirements:
78
- - - ">="
78
+ - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: '0'
80
+ version: '7.2'
81
81
  type: :development
82
82
  prerelease: false
83
83
  version_requirements: !ruby/object:Gem::Requirement
84
84
  requirements:
85
- - - ">="
85
+ - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '0'
87
+ version: '7.2'
88
88
  - !ruby/object:Gem::Dependency
89
89
  name: simplecov
90
90
  requirement: !ruby/object:Gem::Requirement
91
91
  requirements:
92
- - - ">="
92
+ - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '0'
94
+ version: '0.22'
95
95
  type: :development
96
96
  prerelease: false
97
97
  version_requirements: !ruby/object:Gem::Requirement
98
98
  requirements:
99
- - - ">="
99
+ - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: '0.22'
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: test-unit
104
104
  requirement: !ruby/object:Gem::Requirement
105
105
  requirements:
106
- - - ">="
106
+ - - "~>"
107
107
  - !ruby/object:Gem::Version
108
- version: '0'
108
+ version: '3.7'
109
109
  type: :development
110
110
  prerelease: false
111
111
  version_requirements: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - ">="
113
+ - - "~>"
114
114
  - !ruby/object:Gem::Version
115
- version: '0'
115
+ version: '3.7'
116
116
  description: A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby.
117
117
  Provides Rails ActionView template handlers for ERB and Haml.
118
118
  email:
@@ -168,9 +168,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
168
  - !ruby/object:Gem::Version
169
169
  version: '0'
170
170
  requirements: []
171
- rubygems_version: 3.4.10
171
+ rubygems_version: 3.2.33
172
172
  signing_key:
173
173
  specification_version: 4
174
- summary: A library for safe evaluation of Ruby code based on ParseTree/RubyParser
175
- and Ruby2Ruby
174
+ summary: A library for safe evaluation of Ruby code based on RubyParser and Ruby2Ruby
176
175
  test_files: []